[nhin-d] push by gm2...@cerner.com - Fixing issue with timeouts in cached secret key manager.... on 2014-12-18 00:42 GMT

2 views
Skip to first unread message

nhi...@googlecode.com

unread,
Dec 17, 2014, 7:43:04 PM12/17/14
to nhindirec...@googlegroups.com
Revision: d6dc694b338d
Branch: default
Author: gm2552
Date: Thu Dec 18 00:42:12 2014 UTC
Log: Fixing issue with timeouts in cached secret key manager.
Adding tag for direct-common-1.4.2.
https://code.google.com/p/nhin-d/source/detail?r=d6dc694b338d

Added:
/java/tags/direct-common-1.4.2/pom.xml

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AbstractAuditor.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditContext.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditEvent.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/Auditor.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditorFactory.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditorMBean.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/DefaultAuditContext.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/annotation/AuditFile.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/annotation/MultiproviderAuditors.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/annotation/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/FileAuditor.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/LoggingAuditor.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/MultiProviderAuditor.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/NoOpAuditor.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/module/ProviderAuditorModule.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/module/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/FileAuditorProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/LoggingAuditorProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/MultiProviderAuditorProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/NoOpAuditorProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/SPIAuditorProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/KeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/MutableKeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/PKCS11Credential.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/exceptions/CryptoException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/exceptions/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/AbstractPKCS11TokenKeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedKeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedPKCS11Credential.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/DynamicPKCS11TokenKeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/StaticCachedPKCS11TokenKeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/StaticPKCS11TokenKeyStoreProtectionManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/CommandLineTokenLoginCallback.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManagerUI.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/TokenLoginCallback.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/commands/KeyModel.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/commands/PKCS11Commands.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/commands/printers/KeyPrinter.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/MDNStandard.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/MailStandard.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/MailUtil.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/SMIMEStandard.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/DSNFailureTextBodyPartGenerator.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/DSNGenerator.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/DSNMessageHeaders.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/DSNRecipientHeaders.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/DSNStandard.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/impl/DefaultDSNFailureTextBodyPartGenerator.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/impl/HumanReadableTextAssembler.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/impl/HumanReadableTextAssemblerFactory.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/impl/NoEscapeXMLOutputter.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/impl/UnescapedAwareXMLOutputter.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/impl/UnescapedText.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractBasicAuthServiceSecurityManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractDeleteRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractGetRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractPostRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractPutRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractSecuredService.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/AbstractUnsecuredService.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/BootstrapBasicAuthServiceSecurityManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/HttpClientFactory.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/OpenServiceSecurityManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/SecuredServiceRequestBase.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/ServiceRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/ServiceSecurityManager.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/UnsecuredServiceRequestBase.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/BasicAuthCredential.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/BasicAuthCredentialStore.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/BasicAuthValidator.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/NHINDPrincipal.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/exceptions/BasicAuthException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/exceptions/NoSuchUserException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/exceptions/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/impl/AbstractBasicAuthValidator.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/impl/BasicAuthFilter.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/impl/BootstrapBasicAuthCredentialStore.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/impl/DefaultBasicAuthCredential.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/impl/HashableBasicAuthValidator.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/impl/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/auth/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/exceptions/AuthException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/exceptions/AuthorizationException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/exceptions/ServiceException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/exceptions/ServiceMethodException.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/exceptions/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/provider/BootstrapBasicAuthServiceSecurityManagerProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/provider/OpenServiceSecurityManagerProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/rest/provider/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/Action.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/Command.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/CommandDef.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/CommandUsage.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/Commands.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/StringArrayUtil.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/printer/AbstractRecordPrinter.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tooling/printer/RecordPrinter.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/TxDetailParser.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/TxService.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/TxUtil.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/impl/DefaultTxDetailParser.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/impl/NoOpTxServiceClient.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/impl/RESTTxServiceClient.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/impl/SuppressNotificationRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/impl/TrackMessageRequest.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/model/Tx.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/model/TxDetail.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/model/TxDetailType.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/model/TxMessageType.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/model/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/module/DefaultTxDetailParserModule.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/module/ProviderTxServiceModule.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/package-info.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/provider/DefaultTxDetailParserProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/provider/NoOpTxServiceClientProvider.java

/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/tx/provider/RESTTxServiceClientProvider.java
/java/tags/direct-common-1.4.2/src/report/findbugs-exclude.xml
/java/tags/direct-common-1.4.2/src/site/resources/css/site.css
/java/tags/direct-common-1.4.2/src/site/resources/images/logo.png
/java/tags/direct-common-1.4.2/src/site/site.xml
/java/tags/direct-common-1.4.2/src/site/xdoc/index.xml
/java/tags/direct-common-1.4.2/src/test/java/BOGScraper.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/BaseTestPlan.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/ServiceRunner.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/TestApplicationContext.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/AuditEventTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/AuditorFactoryTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/DefaultAuditContextTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/impl/ExceptionAuditor.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/impl/FileAuditorTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/impl/LoggingAuditorTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/impl/MultiProviderAuditorTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/impl/NoOpAuditorTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/provider/FileAuditorProviderTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/provider/MultiProviderAuditorProviderTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/audit/provider/SPIAuditorProviderTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/crypto/impl/BootstrapTestCallbackHandler.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/crypto/impl/BootstrappedKeyStoreProtectionManagerTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/crypto/impl/DynamicPKCS11TokenKeyStoreProtectionManagerTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/crypto/impl/StaticPKCS11TokenKeyStoreProtectionManagerTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/mail/dsn/DNSGenerator_CreateDSNMessageTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/AbstractUnsecuredService_callWithRetryTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/AbstractUnsecuredService_constructTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/HttpClientFactory_createHttpClientTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/MockService.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/MockServiceRequest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/UnsecureServiceRequestBase_callTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/UnsecuredServiceRequestBase_escapeURITest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/UnsecuredServiceRequestBase_handleUnauthorizedTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/UnsecuredServiceRequestBase_interpretResponseTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/UsecuredServiceRequestBase_checkContentTypeTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/UsecuredServiceRequestBase_constructTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/auth/impl/BasicAuthFilter_doFilterTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/auth/impl/HashableBasicAuthValidator_authenticateRawTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/auth/impl/HashableBasicAuthValidator_authenticateTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/auth/impl/HashableBasicAuthValidator_convertPassToHashTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/rest/auth/impl/HashableBasicAuthValidator_setHashTypeTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/TxUtil_getMessageTypeTypeTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/TxUtil_isRelAndTimelyTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/impl/DefaultTxDetailParser_getMessageDetails_OptionalInputsTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/impl/DefaultTxDetailParser_getMimeMessageDetailsTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/impl/RESTTxServiceClient_addTxTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/impl/RESTTxServiceClient_suppressNotificationTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/mock/MockTxsResource.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/mock/TxJSONProvider.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/model/TxDetailTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/model/TxDetail_toStringTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/model/TxTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/tx/model/Tx_toStringTest.java

/java/tags/direct-common-1.4.2/src/test/java/org/nhindirect/common/util/TestUtils.java
/java/tags/direct-common-1.4.2/src/test/resources/applicationContext.xml
/java/tags/direct-common-1.4.2/src/test/resources/messages/DSNMessage.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/DSNMessageNoActionOrStatus.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/DSNMessageOrigInReplyTo.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/MDNDispatchedTimeAndReliable.txt
/java/tags/direct-common-1.4.2/src/test/resources/messages/MDNMessage.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/MDNMessageNoDisp.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/MDNMessageNoFinalRecip.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/MDNMessageOrigInReplyTo.txt

/java/tags/direct-common-1.4.2/src/test/resources/messages/MessageWithAttachment.txt
/java/tags/direct-common-1.4.2/src/test/resources/messages/SMIMEMessage.txt
/java/tags/direct-common-1.4.2/src/test/resources/pkcs11Config/keyStore.cfg
/java/tags/direct-common-1.4.2/src/test/resources/pkcs11Config/pkcs11.cfg
/java/tags/direct-common-1.4.2/src/test/resources/webapp/WEB-INF/web.xml
Modified:

/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/StaticCachedPKCS11TokenKeyStoreProtectionManager.java
/java/direct-common/src/site/apt/releaseNotes.apt

=======================================
--- /dev/null
+++ /java/tags/direct-common-1.4.2/pom.xml Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd ">
+ <groupId>org.nhind</groupId>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>direct-common</artifactId>
+ <name>Direct Project common APIs</name>
+ <version>1.4.2</version>
+ <description>Direct Project common APIs. Includes instrumentation,
auditing, and other utility APIs</description>
+ <inceptionYear>2010</inceptionYear>
+
<url>http://api.nhindirect.org/x/www/api.nhindirect.org/java/site/direct-common/${project.version}</url>
+ <developers>
+ <developer>
+ <name>Greg Meyer</name>
+ <id>GM2552</id>
+ <email>gm2...@cerner.com</email>
+ <roles>
+ <role>owner</role>
+ </roles>
+ </developer>
+ </developers>
+ <organization>
+ <name>The Direct Project</name>
+ <url>http://nhindirect.org</url>
+ </organization>
+ <prerequisites>
+ <maven>2.0.4</maven>
+ </prerequisites>
+ <scm>
+
<url>http://code.google.com/p/nhin-d/source/browse/#hg/java/direct-common</url>
+
<connection>scm:hg:https://nhin-d.googlecode.com/hg/nhin-d/java/direct-common</connection>
+ </scm>
+ <issueManagement>
+ <system>Google Code</system>
+ <url>http://code.google.com/p/nhin-d/issues/list</url>
+ </issueManagement>
+ <licenses>
+ <license>
+ <name>New BSD License</name>
+ <url>http://nhindirect.org/BSDLicense</url>
+ </license>
+ </licenses>
+ <repositories>
+ <repository>
+ <id>REPO2</id>
+ <name>Maven2 Central Repo2</name>
+ <url>http://repo2.maven.org/maven2/</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4.3</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>dsn</artifactId>
+ <version>1.4.3</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-jaxrs</artifactId>
+ <version>1.7.5</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>enunciate-core-annotations</artifactId>
+ <version>1.23</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>4.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <type>jar</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey.contribs</groupId>
+ <artifactId>jersey-spring</artifactId>
+ <version>1.6</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </exclusion>
+ </exclusions>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>2.5.6</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-servlet-tester</artifactId>
+ <version>6.1.14</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.mina</groupId>
+ <artifactId>mina-core</artifactId>
+ <version>1.0.2</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ </exclusion>
+ </exclusions>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.8.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav</artifactId>
+ <version>RELEASE</version>
+ </extension>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ <version>1.0-beta-6</version>
+ </extension>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>1.0-beta-6</version>
+ </extension>
+ </extensions>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <targetPath>lib</targetPath>
+ <directory>${project.basedir}/lib</directory>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ </testResource>
+ <testResource>
+ <targetPath>lib</targetPath>
+ <directory>${project.basedir}/lib</directory>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <phase>compile</phase>
+ </execution>
+ </executions>
+ <configuration>
+ <fork>true</fork>
+ <optimize>true</optimize>
+ <showDeprecation>true</showDeprecation>
+ <encoding>UTF-8</encoding>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.0.3</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>com.atlassian.maven.plugins</groupId>
+ <artifactId>maven-clover2-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <jdk>1.6</jdk>
+ <licenseLocation>
+ ${project.basedir}/../licenses/clover.license
+ </licenseLocation>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>instrument</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <index>true</index>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- for releases only
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.6.1</version>
+ <configuration>
+ <charset>UTF-8</charset>
+ <docencoding>UTF-8</docencoding>
+ <docfilessubdirs>true</docfilessubdirs>
+ <detectJavaApiLink>true</detectJavaApiLink>
+ <detectLinks>true</detectLinks>
+ <source>1.6</source>
+ <show>public</show>
+ <excludePackageNames>
+
org.nhindirect.common.mail.dsn.impl:org.nhindirect.common.tx.impl:org.nhindirect.common.tx.provider:org.nhindirect.common.tx.module:org.nhindirect.common.tooling:org.nhindirect.common.crypto.tools
+ </excludePackageNames>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>package</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.0</version>
+ <configuration>
+
<tagBase>scm:hg:https://nhin-d.googlecode.com/hg/nhin-d/java/tags</tagBase>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>2.1.1</version>
+ <dependencies>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>2.1.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.6.1</version>
+ <configuration>
+ <charset>UTF-8</charset>
+ <docencoding>UTF-8</docencoding>
+ <docfilessubdirs>true</docfilessubdirs>
+ <detectJavaApiLink>true</detectJavaApiLink>
+ <detectLinks>true</detectLinks>
+ <source>1.6</source>
+ <show>public</show>
+ <excludePackageNames>
+
org.nhindirect.common.mail.dsn.impl:org.nhindirect.common.tx.impl:org.nhindirect.common.tx.provider:org.nhindirect.common.tx.module:org.nhindirect.common.tooling:org.nhindirect.common.crypto.tools
+ </excludePackageNames>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <configuration>
+ <targetJdk>1.6</targetJdk>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changelog-plugin</artifactId>
+ <configuration>
+ <dates>
+ <!-- Insert the date of the most recent release -->
+ <date>2011-01-15</date>
+ </dates>
+ <outputEncoding>UTF-8</outputEncoding>
+ <type>date</type>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>clirr-maven-plugin</artifactId>
+ <configuration>
+ <minSeverity>info</minSeverity>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <effort>Max</effort>
+
<excludeFilterFile>${project.basedir}/src/report/findbugs-exclude.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>taglist-maven-plugin</artifactId>
+ <configuration>
+ <tags>
+ <tag>FIXME</tag>
+ <tag>TODO</tag>
+ <tag>WARN</tag>
+ <tag>@deprecated</tag>
+ </tags>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>com.atlassian.maven.plugins</groupId>
+ <artifactId>maven-clover2-plugin</artifactId>
+ <version>3.1.0</version>
+ <configuration>
+ <licenseLocation>
+ ${project.basedir}/../licenses/clover.license
+ </licenseLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+ <distributionManagement>
+ <site>
+ <id>nhind-site</id>
+ <name>NHIN Direct API publication site</name>
+
<url>sftp://api.nhindirect.org/x/www/api.nhindirect.org/java/site/direct-common/${project.version}</url>
+ </site>
+ <snapshotRepository>
+ <id>sonatype-snapshot</id>
+ <name>Sonatype OSS Maven SNAPSHOT Repository</name>
+ <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ <repository>
+ <id>sonatype-release</id>
+ <name>Sonatype OSS Maven Release Repositor</name>
+
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ <uniqueVersion>false</uniqueVersion>
+ </repository>
+ </distributionManagement>
+</project>
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AbstractAuditor.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,73 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.UUID;
+
+/**
+ * Abstract base class {@link Auditor} that performs trivial sanity checks
such as parameter validation. All calls are delegated to
+ * {@link #writeEvent(String, Calendar, String, String, Collection) which
is implemented by a concrete sub class to commit the event to the
+ * underlying medium. Before calling {@link #writeEvent(String, Calendar,
String, String, Collection), a unique event id and time stamp is generated.
+ *
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public abstract class AbstractAuditor implements Auditor
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void audit(String principal, AuditEvent event)
+ {
+ audit(principal, event, null);
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void audit(String principal, AuditEvent event, Collection<?
extends AuditContext> contexts)
+ {
+ if (principal == null || principal.isEmpty())
+ throw new IllegalArgumentException("Principal cannot be null or empty");
+
+ if (event == null)
+ throw new IllegalArgumentException("Event cannot be null");
+
+ writeEvent(UUID.randomUUID(), Calendar.getInstance(), principal, event,
contexts);
+ }
+
+ /**
+ * Writes the auditable event to the storage medium.
+ * @param eventId An arbitrary unique ID for the event.
+ * @param eventTimeStamp The date/time that the event record was created.
+ * @param principal An identifier of the entity that performed the
event. This may be an actual user performing a workflow or a system entity
+ * performing back office processing. Cannot be null or empty.
+ * @param event The event that was performed and that will be audited.
Cannot be null
+ * @param contexts A collection of contexts that provide additional
information for the event.
+ */
+ public abstract void writeEvent(UUID eventId, Calendar eventTimeStamp,
String principal, AuditEvent event, Collection<? extends AuditContext>
contexts);
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditContext.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,43 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+/**
+ * Provides additional contextual information for an auditable event.
Context consists of a free text context name and a String based value of the
+ * context. Examples of contexts may be message IDs, message sources,
authenticated users, etc.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public interface AuditContext
+{
+ /**
+ * Gets the name of the context.
+ * @return The name of the context.
+ */
+ public String getContextName();
+
+ /**
+ * Gets the String based value of the context.
+ * @return The String based value of the context.
+ */
+ public String getContextValue();
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditEvent.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,102 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+/**
+ * A high level descriptor of an auditable event. Attributes include a
name which describes a high level "category" of the event and a type that
further
+ * qualifies that the event.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class AuditEvent
+{
+ private final String name;
+ private final String type;
+
+ /**
+ * Constructs an audit event from a name and type.
+ * @param name The generic name or "category" of the event. Cannot be
null or empty.
+ * @param type A type that further describes the category. Cannot be
null or empty.
+ */
+ public AuditEvent(String name, String type)
+ {
+ if (name == null || name.isEmpty())
+ throw new IllegalArgumentException();
+
+ if (type == null || type.isEmpty())
+ throw new IllegalArgumentException();
+
+ this.name = name;
+ this.type = type;
+ }
+
+ /**
+ * Gets the name of the event.
+ * @return The name of the event
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Gets the type of the event.
+ * @return The type of the event
+ */
+ public String getType()
+ {
+ return type;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder("EventName: ");
+ builder.append(name).append("\r\nEvent Type: ").append(type);
+
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode()
+ {
+ return toString().hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null || !(obj instanceof AuditEvent))
+ return false;
+
+ return obj.hashCode() == hashCode();
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/Auditor.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,58 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+import java.util.Collection;
+
+/**
+ * The auditor interface defines the auditing sub-system of the Direct
Project. Auditable events consists of event descriptor, a principal, and
+ * a collection of contextual information. The auditing implementation
may use any
+ * appropriate medium and format to store audit events. Some
implementations may even consist of multiple audit implementation providers.
+ * <p>
+ *
+ * Auditor implementations should be thread safe and not block for
relatively long periods of time to commit audit events to the underlying
+ * storage medium.
+ *
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public interface Auditor
+{
+ /**
+ * Writes an {@link AuditEvent} to the audit sub-system.
+ * @param principal An identifier of the entity that performed the
event. This may be an actual user performing a workflow or a system entity
+ * performing back office processing. Cannot be null or empty.
+ * @param event The event that was performed and that will be audited.
Cannot be null.
+ */
+ public void audit(String principal, AuditEvent event);
+
+ /**
+ * Writes an {@link AuditEvent} to the audit sub-system with addition
contextual data.
+ * @param principal An identifier of the entity that performed the
event. This may be an actual user performing a workflow or a system entity
+ * performing back office processing. Cannot be null or empty.
+ * @param event The event that was performed and that will be audited.
Cannot be null
+ * @param contexts A collection of contexts that provide additional
information for the event.
+ */
+ public void audit(String principal, AuditEvent event, Collection<?
extends AuditContext> contexts);
+
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditorFactory.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,91 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.nhindirect.common.audit.module.ProviderAuditorModule;
+import org.nhindirect.common.audit.provider.LoggingAuditorProvider;
+import org.nhindirect.common.audit.provider.SPIAuditorProvider;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+
+/**
+ * Factory for creating {@link Auditor} instances. Each call the
createAuditor results in a new Auditor instance (the factory does not
+ * use a singleton pattern).
+ *
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class AuditorFactory
+{
+ /**
+ * Creates an {@link Auditor} by searching for configured implementations
using Java SPI. If no implementation are found, a default
+ * instance using the configured logging sub-system is created.
+ * @return An new auditor instance.
+ */
+ public static synchronized Auditor createAuditor()
+ {
+ final SPIAuditorProvider spiProv = new SPIAuditorProvider();
+
+ final Provider<Auditor> provider = spiProv.isImplementationAvailable() ?
spiProv : new LoggingAuditorProvider();
+
+ return createAuditor(provider);
+ }
+
+ /**
+ * Creates an {@link Auditor} using a Guice provider.
+ * @param provider The provider using to create Auditor instances.
+ * @return An new auditor instance.
+ */
+ public static synchronized Auditor createAuditor(Provider<Auditor>
provider)
+ {
+ if (provider == null)
+ throw new IllegalArgumentException("Provider cannot be null.");
+
+ final ProviderAuditorModule module =
ProviderAuditorModule.create(provider);
+
+ final Collection<Module> modules = new ArrayList<Module>();
+ modules.add(module);
+
+ return createAuditor(modules);
+ }
+
+ /**
+ * Creates an {@link Auditor} using one or more Guice modules.
+ * @param modules A collections modules used to configure a Guice
injector.
+ * @return An new auditor instance.
+ */
+ public static synchronized Auditor createAuditor(Collection<Module>
modules)
+ {
+ if (modules == null || modules.size() == 0)
+ throw new IllegalArgumentException("Modules cannot be null or empty");
+
+ final Injector configInjector = Guice.createInjector(modules);
+
+ return configInjector.getInstance(Auditor.class);
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/AuditorMBean.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,58 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+import javax.management.openmbean.CompositeData;
+
+/**
+ * MBean interface for an {@link Auditor}
+ * @author Greg Meyer
+ *
+ */
+public interface AuditorMBean
+{
+ /**
+ * Gets the number of events in the event the auditing system.
+ * @return The number of events in the event the auditing system.
+ */
+ public Integer getEventCount();
+
+ /**
+ * Gets the event data in the audit system.
+ * @param eventCount The number of events to retrieve. Events are
retrieved from the most recent event.
+ * @return Event data in the audit system.
+ */
+ public CompositeData[] getEvents(Integer eventCount);
+
+ /**
+ * Gets the latest event to be written to the audit system.
+ * @return The latest event to be written to the audit system.
+ */
+ public CompositeData getLastEvent();
+
+ /**
+ * Clears the audit repository.
+ */
+ public void clear();
+
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/DefaultAuditContext.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,77 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit;
+
+/**
+ * Default implementation of the {@link AuditContext} interface that takes
a simple name/value pair.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class DefaultAuditContext implements AuditContext
+{
+ private final String name;
+ private final String value;
+
+ /**
+ * Constructs an context with a simple name and value.
+ * @param name The name of the context.
+ * @param value The string based value of the context.
+ */
+ public DefaultAuditContext(String name, String value)
+ {
+ if (name == null || name.isEmpty())
+ throw new IllegalArgumentException("Name cannot be null or empty.");
+
+ if (value == null)
+ throw new IllegalArgumentException("Name cannot be null");
+
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getContextName()
+ {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getContextValue()
+ {
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString()
+ {
+ return name + ":" + value;
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/annotation/AuditFile.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,15 @@
+package org.nhindirect.common.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.google.inject.BindingAnnotation;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target( {ElementType.FIELD, ElementType.PARAMETER})
+@BindingAnnotation
+public @interface AuditFile {
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/annotation/MultiproviderAuditors.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,16 @@
+package org.nhindirect.common.audit.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import com.google.inject.BindingAnnotation;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target( {ElementType.FIELD, ElementType.PARAMETER})
+@BindingAnnotation
+public @interface MultiproviderAuditors
+{
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/annotation/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,5 @@
+/**
+ * Guice annotations for auditor classes.
+ */
+
+package org.nhindirect.common.audit.annotation;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/FileAuditor.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,631 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.impl;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.management.ManagementFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.UUID;
+import java.util.Vector;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nhindirect.common.audit.AbstractAuditor;
+import org.nhindirect.common.audit.AuditContext;
+import org.nhindirect.common.audit.AuditEvent;
+import org.nhindirect.common.audit.AuditorMBean;
+import org.nhindirect.common.audit.annotation.AuditFile;
+
+import com.google.inject.Inject;
+import javax.management.openmbean.ArrayType;
+
+/**
+ * File based auditor. Events are stored in a non-circular flat file that
is not truncated. Each event is appended to the end of the audit file.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class FileAuditor extends AbstractAuditor implements AuditorMBean
+{
+ private static final Log LOGGER =
LogFactory.getFactory().getInstance(FileAuditor.class);
+
+ /* record meta data goes at the end of each record */
+ private static final short RECORD_METADATA_SIZE = 36;
+
+ private static final int RECORD_META_WRAPPER = 0xFFFFFFFF;
+
+ private static final DateFormat df =
DateFormat.getDateInstance(DateFormat.LONG, Locale.getDefault());
+
+
+ private static final String EVENT_ID = "EVENT ID";
+ private static final String EVENT_PRINCIPAL = "EVENT PRINCIPAL";
+ private static final String EVENT_TIME = "EVENT TIME";
+ private static final String EVENT_NAME = "EVENT CATEGORY";
+ private static final String EVENT_TYPE = "EVENT MESSAGE";
+ private static final String EVENT_CTX = "EVENT CONTEXTS";
+
+ private static final String EVENT_TAG_DELIMITER = "@@@@\r\n";
+ private static final String CONTEXT_TAG_DELIMITER = "====\r\n";
+
+ private final RandomAccessFile auditFile;
+ private AtomicInteger recordCount = new AtomicInteger();
+
+ private CompositeType eventType;
+ private String[] itemNames;
+
+
+ /**
+ * Constructor. If the audit file does not exist, then a new file is
created barring access permissions or illegal file names or locations. If
the file already
+ * existing, then the file opened in append mode and new events are
written to the end of the file.
+ * @param auditFile File descriptor of the audit file.
+ */
+ @Inject
+ public FileAuditor(@AuditFile File auditFile)
+ {
+ if (auditFile == null)
+ throw new IllegalArgumentException("Audit file cannot be null.");
+
+ LOGGER.info("Instantiating FileAuditor");
+
+ if (!auditFile.exists())
+ {
+ LOGGER.info("Audit file does not exist. Creating new file " +
auditFile.getAbsolutePath());
+ try
+ {
+ if (!auditFile.createNewFile())
+ throw new IllegalArgumentException("Audit file could not be
created.");
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Audit file could not be created.",
e);
+ }
+ }
+ else
+ LOGGER.info("Found existing audit file " + auditFile.getAbsolutePath()
+ " Opening in read/write mode.");
+
+ try
+ {
+ this.auditFile = new RandomAccessFile(auditFile, "rw");
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new IllegalArgumentException("Audit file could not be found or
created.", e);
+ }
+
+ // initialize the auditor state and validate that the file is not corrupt
+ initAuditor();
+
+ // register the auditor as an MBean
+ registerMBean();
+ }
+
+ /*
+ * Initialize the auditor. This includes consistency checks for
corruption
+ */
+ private void initAuditor()
+ {
+ try
+ {
+ if (auditFile.length() == 0)
+ {
+ // new file
+ recordCount.set(0);
+ auditFile.seek(0);
+ }
+ else
+ {
+ // existing file
+ // check it to make sure it is not corrupt
+
+ // set the current file position to the last valid record
+ long currentPosition = auditFile.length();
+
+ // start at the end of the file and work backwards
+ boolean foundValidRecord = false;
+ boolean needsFixing = false;
+ while (currentPosition >= RECORD_METADATA_SIZE)
+ {
+ foundValidRecord = isCurrentRecordValid(currentPosition);
+ if (foundValidRecord)
+ break;
+ else if (!needsFixing)
+ {
+ LOGGER.warn("Inconsistencies found in audit file. Attempting to fix
issues. Some data may be lost.");
+ needsFixing = true;
+ }
+
+ --currentPosition;
+ }
+
+ // if we could not find a valid record, then just start over
+ if (!foundValidRecord)
+ {
+ recordCount.set(0);
+ auditFile.seek(0);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("Audit file is corrupt or could not be
read.", e);
+ }
+ }
+
+ /*
+ * Register the MBean
+ */
+ private void registerMBean()
+ {
+
+ LOGGER.info("Registering FileAuditor MBean");
+
+ try
+ {
+ itemNames = new String[] {"Event Id", "Event Time", "Event
Principal", "Event Name", "Event Type", "Contexts"};
+
+ OpenType<?>[] types = {SimpleType.STRING, SimpleType.STRING,
SimpleType.STRING, SimpleType.STRING,
+ SimpleType.STRING, ArrayType.getArrayType(SimpleType.STRING)};
+
+ eventType = new CompositeType("AuditEvent", "Direct Auditable Event",
itemNames, itemNames, types);
+ }
+ catch (OpenDataException e)
+ {
+ LOGGER.error("Failed to create settings composite type: " +
e.getLocalizedMessage(), e);
+ return;
+ }
+
+ Class<?> clazz = this.getClass();
+ final StringBuilder objectNameBuilder = new
StringBuilder(clazz.getPackage().getName());
+ objectNameBuilder.append(":type=").append(clazz.getSimpleName());
+ objectNameBuilder.append(",name=").append(UUID.randomUUID());
+
+ try
+ {
+ final StandardMBean mbean = new StandardMBean(this, AuditorMBean.class);
+
+ final MBeanServer mbeanServer =
ManagementFactory.getPlatformMBeanServer();
+ mbeanServer.registerMBean(mbean, new
ObjectName(objectNameBuilder.toString()));
+ }
+ catch (JMException e)
+ {
+ LOGGER.error("Unable to register the FileAuditor MBean", e);
+ }
+ }
+
+ /*
+ * Ensure that the record at the given position is valid
+ */
+ private boolean isCurrentRecordValid(long currentFilePosition) throws
IOException
+ {
+ boolean validRecord = true;
+
+ auditFile.seek(currentFilePosition - RECORD_METADATA_SIZE);
+
+ // verify the last record is legit
+ int start = auditFile.readInt();
+ int size = auditFile.readInt();
+ recordCount.set(auditFile.readInt());
+
+ byte[] sha1 = new byte[20];
+ auditFile.read(sha1);
+
+ int end = auditFile.readInt();
+
+ // verify the start and end of the meta data
+ validRecord = (start == RECORD_META_WRAPPER && end ==
RECORD_META_WRAPPER);
+ if (validRecord)
+ {
+ // calculate the SHA1 of the message
+ auditFile.seek(currentFilePosition - RECORD_METADATA_SIZE - size);
+ byte[] message = new byte[size];
+
+ auditFile.read(message);
+
+ // calculate the SHA1 hash of the message
+ byte[] digest = generateDigest(message);
+
+ validRecord = Arrays.equals(digest, sha1);
+ }
+
+ // set the file position back to where we found it
+ auditFile.seek(currentFilePosition);
+
+ return validRecord;
+ }
+
+ /*
+ * generates a SHA1 digest of a message
+ */
+ private byte[] generateDigest(byte[] message)
+ {
+ // calculate the SHA1 hash of the message
+ try
+ {
+ MessageDigest md = MessageDigest.getInstance("SHA1");
+ md.update(message);
+ return md.digest();
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return new byte[] {};
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeEvent(UUID eventId, Calendar eventTimeStamp, String
principal, AuditEvent event, Collection<? extends AuditContext> contexts)
+ {
+ ///CLOVER:OFF
+ if (LOGGER.isDebugEnabled())
+ {
+ StringBuilder builder = new StringBuilder("Attempting to write new
event to the audit store.");
+ builder.append("\r\n\t Event Id: ").append(eventId.toString());
+ builder.append("\r\n\t Event
Time: ").append(df.format(eventTimeStamp.getTime()));
+ builder.append("\r\n\t Event Principal: ").append(principal);
+ builder.append("\r\n\t Event Name: ").append(event.getName());
+ builder.append("\r\n\t Event Type: ").append(event.getType());
+ LOGGER.trace(builder.toString());
+ }
+ ///CLOVER:ON
+
+ String recordText = buildRecordText(eventId, eventTimeStamp, principal,
event, contexts);
+
+ byte[] messageBytes = recordText.getBytes();
+
+ // generate the SHA1
+ byte[] sha1 = generateDigest(messageBytes);
+
+ try
+ {
+ // write the message out
+ auditFile.writeInt(messageBytes.length);
+ auditFile.write(messageBytes);
+ auditFile.writeInt(RECORD_META_WRAPPER);
+ auditFile.writeInt(messageBytes.length);
+ auditFile.writeInt(recordCount.incrementAndGet());
+ auditFile.write(sha1);
+ auditFile.writeInt(RECORD_META_WRAPPER);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("The audit file cannot be written to.",
e);
+ }
+ }
+
+ /*
+ * builds the text of the record that will be placed in the file
+ */
+ private String buildRecordText(UUID eventId, Calendar eventTimeStamp,
String principal, AuditEvent event, Collection<? extends AuditContext>
contexts)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("\r\n" + EVENT_ID + ": " + eventId + EVENT_TAG_DELIMITER);
+ builder.append("\t" + EVENT_TIME + ": " +
df.format(eventTimeStamp.getTime()) + EVENT_TAG_DELIMITER);
+ builder.append("\t" + EVENT_PRINCIPAL + ": " + principal +
EVENT_TAG_DELIMITER);
+ builder.append("\t" + EVENT_NAME + ": " + event.getName() +
EVENT_TAG_DELIMITER);
+ builder.append("\t" + EVENT_TYPE + ": " + event.getType() +
EVENT_TAG_DELIMITER);
+
+ if (contexts != null && contexts.size() > 0)
+ {
+ builder.append("\t" + EVENT_CTX + CONTEXT_TAG_DELIMITER);
+ for (AuditContext context : contexts)
+ builder.append("\t\t" + context.getContextName() + ":" +
context.getContextValue() + CONTEXT_TAG_DELIMITER);
+
+ builder.append(EVENT_TAG_DELIMITER);
+ }
+
+ builder.append("\r\n");
+
+ return builder.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized Integer getEventCount()
+ {
+ return recordCount.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized CompositeData[] getEvents(Integer eventCount)
+ {
+ if (eventType == null || eventCount == 0)
+ return null;
+
+ Vector<CompositeData> retVal = new Vector<CompositeData>();
+
+ /*
+ * Save off the position
+ */
+ long savePosition = -1;
+ try
+ {
+ savePosition = auditFile.getFilePointer();
+ long currentPosition = savePosition;
+
+ // Get the last event
+ CompositeData event = getLastEvent();
+ if (event != null)
+ retVal.add(event);
+
+ // keep getting event until either we have reached the requested count
+ // or there are no more records
+ int cnt = 1;
+ while (cnt < eventCount && event != null)
+ {
+ int size = getRecordSize(currentPosition);
+
+ // move the file pointer to the last record
+ currentPosition -= (RECORD_METADATA_SIZE + size + 4);
+ auditFile.seek(currentPosition);
+ event = getLastEvent();
+
+ if (event != null)
+ retVal.add(event);
+
+ ++cnt;
+ }
+ }
+ catch (IOException e)
+ {
+ /* no-op */
+ }
+ finally
+ {
+ try
+ {
+ // set the file point back to the orignal position
+ if (savePosition > -1)
+ auditFile.seek(savePosition);
+ }
+ catch (IOException e) {/* no-op */}
+ }
+
+ return (retVal.size() > 0) ? retVal.toArray(new
CompositeData[retVal.size()]) : null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized CompositeData getLastEvent()
+ {
+ if (eventType == null)
+ return null;
+
+ CompositeData retVal = null;
+
+ long currentPosition = -1;
+ try
+ {
+ // save off the current position and get the last event
+ currentPosition = auditFile.getFilePointer();
+
+ retVal = getEvent(currentPosition);
+
+ }
+ catch (IOException e)
+ {
+ /* no-op */
+ }
+ finally
+ {
+ try
+ {
+ // set the file position back to the original position
+ if (currentPosition > -1)
+ auditFile.seek(currentPosition);
+ }
+ catch (IOException e) {/* no-op */}
+ }
+
+ return retVal;
+ }
+
+ /*
+ * Gets the size of a record at the before the current file posistion
+ */
+ private int getRecordSize(long position)
+ {
+ int retVal = -1;
+
+ try
+ {
+ long currentPosition = position;
+ if (getEventCount() > 0 && currentPosition >= RECORD_METADATA_SIZE)
+ {
+ auditFile.seek(currentPosition - RECORD_METADATA_SIZE);
+
+ auditFile.readInt();
+ retVal = auditFile.readInt();
+ }
+ }
+ catch (IOException e){}
+ finally
+ {
+ try
+ {
+ // put the file pointer back in the original position
+ auditFile.seek(position);
+ }
+ catch (IOException e) {/* no-op */}
+ }
+
+ return retVal;
+ }
+
+ /*
+ * Get the event prior to the file position
+ */
+ private CompositeData getEvent(long position)
+ {
+ CompositeData retVal = null;
+
+ try
+ {
+ long currentPosition = position;
+ if (getEventCount() > 0 && currentPosition >= RECORD_METADATA_SIZE)
+ {
+ int size = this.getRecordSize(position);
+
+ if (size > 0)
+ {
+ // go to the beginning of the record
+ auditFile.seek(currentPosition - RECORD_METADATA_SIZE - size);
+
+
+ byte[] message = new byte[size];
+
+ // read the message
+ auditFile.read(message);
+ String strMessage = new String(message);
+
+ // split into an array using the event delimiter
+ String[] eventTags = strMessage.split(EVENT_TAG_DELIMITER);
+
+ String id = "";
+ String time = "";
+ String principal = "";
+ String name = "";
+ String type = "";
+ String[] contexts = null;
+
+ for (String tag : eventTags)
+ {
+ tag = tag.trim();
+
+ if (tag.startsWith(EVENT_ID))
+ id = getItemText(tag);
+ else if (tag.startsWith(EVENT_TIME))
+ time = getItemText(tag);
+ else if (tag.startsWith(EVENT_PRINCIPAL))
+ principal = getItemText(tag);
+ else if (tag.startsWith(EVENT_NAME))
+ name = getItemText(tag);
+ else if (tag.startsWith(EVENT_TYPE))
+ type = getItemText(tag);
+ else if (tag.startsWith(EVENT_CTX))
+ {
+ // need to add the \r\n back on the end
+ tag += "\r\n";
+ String[] ctx = tag.split(CONTEXT_TAG_DELIMITER);
+ if (ctx.length > 1)
+ {
+ contexts = new String[ctx.length - 1];
+ for (int i = 1; i < ctx.length; ++i)
+ contexts[i-1] = ctx[i].trim();
+ }
+ }
+ }
+
+ if (contexts == null)
+ contexts = new String[] {" "};
+
+ Object[] eventValues = {id, time, principal, name, type, contexts};
+
+ try
+ {
+ // create the record to be returned
+ retVal = new CompositeDataSupport(eventType, itemNames, eventValues);
+ }
+ catch (OpenDataException e)
+ {
+ LOGGER.error("Error create composit data for audit event.", e);
+ }
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ LOGGER.error("Error reading audit file to create audit event composite
data.", e);
+ }
+ finally
+ {
+ try
+ {
+ // put the file pointer back in the original position
+ auditFile.seek(position);
+ }
+ catch (IOException e) { /* no-op */}
+ }
+
+ return retVal;
+ }
+
+ /*
+ * get the text of a specific item tag
+ */
+ private String getItemText(String item)
+ {
+ int index = item.indexOf(":");
+ if (index > -1)
+ {
+ return item.substring(index + 1).trim();
+ }
+
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void clear()
+ {
+ // simply set the file length to 0 and put the file pointer back to the
beginning of the file
+ try
+ {
+ auditFile.setLength(0);
+ auditFile.seek(0);
+ recordCount.set(0);
+ }
+ catch (IOException e) {/*no-op */}
+ }
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/LoggingAuditor.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,90 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.impl;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nhindirect.common.audit.AbstractAuditor;
+import org.nhindirect.common.audit.AuditContext;
+import org.nhindirect.common.audit.AuditEvent;
+import org.nhindirect.common.audit.Auditor;
+
+/**
+ * {@link Auditor} implementation that utilizes the Apache Commons logging
framework as the storage medium for auditing events. Audit events are
distinguished
+ * from other log entries with the tag <i>[DIRECT AUDIT EVENT]</i> in the
log text.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class LoggingAuditor extends AbstractAuditor
+{
+ private static final String EVENT_TAG = "[DIRECT AUDIT EVENT]";
+ private static final String EVENT_ID = "EVENT ID";
+ private static final String EVENT_PRINCIPAL = "EVENT PRINCIPAL";
+ private static final String EVENT_NAME = "EVENT CATEGORY";
+ private static final String EVENT_TYPE = "EVENT MESSAGE";
+ private static final String EVENT_CTX = "EVENT CONTEXTS";
+
+ private final Log writer =
LogFactory.getFactory().getInstance(LoggingAuditor.class);
+
+ /**
+ * Default constructor
+ */
+ public LoggingAuditor()
+ {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeEvent(UUID eventId, Calendar eventTimeStamp, String
principal, AuditEvent event, Collection<? extends AuditContext> contexts)
+ {
+ writer.info(buildEventString(eventId, principal, event, contexts));
+ }
+
+ /*
+ * Builds the string that will be written to the logging sub system.
+ */
+ private String buildEventString(UUID eventId, String principal,
AuditEvent event, Collection<? extends AuditContext> contexts)
+ {
+ StringBuilder builder = new StringBuilder(EVENT_TAG);
+
+ builder.append("\r\n\t" + EVENT_ID + ": " + eventId);
+ builder.append("\r\n\t" + EVENT_PRINCIPAL + ": " + principal);
+ builder.append("\r\n\t" + EVENT_NAME + ": " + event.getName());
+ builder.append("\r\n\t" + EVENT_TYPE + ": " + event.getType());
+
+ if (contexts != null && contexts.size() > 0)
+ {
+ builder.append("\r\n\t" + EVENT_CTX);
+ for (AuditContext context : contexts)
+ builder.append("\r\n\t\t" + context.getContextName() + ":" +
context.getContextValue());
+ }
+
+ return builder.toString();
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/MultiProviderAuditor.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,97 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nhindirect.common.audit.AuditContext;
+import org.nhindirect.common.audit.AuditEvent;
+import org.nhindirect.common.audit.Auditor;
+import org.nhindirect.common.audit.annotation.MultiproviderAuditors;
+
+import com.google.inject.Inject;
+
+/**
+ * {@link Auditor} implementation that wraps multiple auditors. Each call
to audit will result (barring exceptions in the delegated
+ * auditor) in the event being committed to each auditor.
+ *
+ * @author Greg Meyer
+ * @since 1.0
+ *
+ */
+public class MultiProviderAuditor implements Auditor
+{
+ private static final Log LOGGER =
LogFactory.getFactory().getInstance(MultiProviderAuditor.class);
+
+ private final Collection<? extends Auditor> auditors;
+
+ /**
+ * Creates an auditor with multiple internal auditor instances.
+ * @param auditors The internal auditors that will be used to audit
events.
+ */
+ @Inject
+ public MultiProviderAuditor(@MultiproviderAuditors Collection<? extends
Auditor> auditors)
+ {
+ if (auditors == null || auditors.size() == 0)
+ throw new IllegalArgumentException("Auditors collection cannot be null
or empty");
+
+ this.auditors = Collections.unmodifiableCollection(auditors);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void audit(String principal, AuditEvent event)
+ {
+ audit(principal, event, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void audit(String principal, AuditEvent event, Collection<?
extends AuditContext> contexts)
+ {
+ if (principal == null || principal.isEmpty())
+ throw new IllegalArgumentException("Principal cannot be null or empty");
+
+ if (event == null)
+ throw new IllegalArgumentException("Event cannot be null");
+
+ for (Auditor auditor : auditors)
+ {
+ try
+ {
+ auditor.audit(principal, event, contexts);
+ }
+ catch (Exception e)
+ {
+ LOGGER.error("Failed to audit event using auditor " +
auditor.getClass().getName(), e);
+ }
+ }
+ }
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/NoOpAuditor.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.impl;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.UUID;
+
+import org.nhindirect.common.audit.AbstractAuditor;
+import org.nhindirect.common.audit.AuditContext;
+import org.nhindirect.common.audit.AuditEvent;
+import org.nhindirect.common.audit.Auditor;
+
+/**
+ * {@link Auditor} implementation that effectively does nothing.
Generally used for unit tests
+ * where auditing is not required.
+ *
+ * @author Greg Meyer
+ * @since 1.0
+ *
+ */
+public class NoOpAuditor extends AbstractAuditor
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeEvent(UUID eventId, Calendar eventTimeStamp, String
principal, AuditEvent event, Collection<? extends AuditContext> contexts)
+ {
+
+ }
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/impl/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,5 @@
+/**
+ * Implementations of the {@link Auditor} interface.
+ */
+
+package org.nhindirect.common.audit.impl;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/module/ProviderAuditorModule.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,64 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.module;
+
+import org.nhindirect.common.audit.Auditor;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provider;
+
+/**
+ * Module used to create auditors based on a auditor provider.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class ProviderAuditorModule extends AbstractModule
+{
+ private final Provider<Auditor> auditorProv;
+
+ /**
+ * Create an instance of a ProviderAuditorModule with an auditor provider.
+ * @param auditorProv The auditor provider used to create auditor
instances.
+ * @return A ProviderAuditorModule instance.
+ */
+ public static ProviderAuditorModule create(Provider<Auditor> auditorProv)
+ {
+ return new ProviderAuditorModule(auditorProv);
+ }
+
+ /*
+ * Constructor
+ */
+ private ProviderAuditorModule(Provider<Auditor> auditorProv)
+ {
+ this.auditorProv = auditorProv;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void configure()
+ {
+ bind(Auditor.class).toProvider(auditorProv);
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/module/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,7 @@
+/**
+ * Guice {@link com.google.inject.Module Modules} for creating {@link
Auditor} instances.
+ */
+
+package org.nhindirect.common.audit.module;
+
+
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,5 @@
+/**
+ * Direct project auditing API. Auditors should be obtained using one of
the three methods in the {@link AuditorFactory} class.
+ */
+
+package org.nhindirect.common.audit;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/FileAuditorProvider.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,47 @@
+package org.nhindirect.common.audit.provider;
+
+import java.io.File;
+
+import org.nhindirect.common.audit.Auditor;
+import org.nhindirect.common.audit.impl.FileAuditor;
+
+import com.google.inject.Provider;
+
+public class FileAuditorProvider implements Provider<Auditor>
+{
+ private final File auditFile;
+
+ /**
+ * Constructor with the logging file location.
+ * @param fileLoc The location of the logging file.
+ */
+ public FileAuditorProvider(String fileLoc)
+ {
+ if (fileLoc == null || fileLoc.isEmpty())
+ throw new IllegalArgumentException("File location cannot be null or
empty");
+
+ auditFile = new File(fileLoc);
+ }
+
+
+ /**
+ * Constructor with a file descriptor of the logging file.
+ * @param fileLoc File descriptor of the logging file.
+ */
+ public FileAuditorProvider(File file)
+ {
+ if (file == null)
+ throw new IllegalArgumentException("File cannot be null");
+
+ auditFile = file;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Auditor get()
+ {
+ return new FileAuditor(auditFile);
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/LoggingAuditorProvider.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,53 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+
+package org.nhindirect.common.audit.provider;
+
+import org.nhindirect.common.audit.Auditor;
+import org.nhindirect.common.audit.impl.LoggingAuditor;
+
+import com.google.inject.Provider;
+
+/**
+ * Guice provider for creating {@link LoggingAuditor} instances.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class LoggingAuditorProvider implements Provider<Auditor>
+{
+ /**
+ * Default constructor.
+ */
+ public LoggingAuditorProvider()
+ {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Auditor get()
+ {
+ return new LoggingAuditor();
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/MultiProviderAuditorProvider.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,89 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.provider;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.nhindirect.common.audit.Auditor;
+import org.nhindirect.common.audit.impl.MultiProviderAuditor;
+
+import com.google.inject.Provider;
+
+/**
+ * Guice provider for creating {@link MultiProviderAuditor} instances.
The provider can take either existing {@link Auditor} instances or
providers for creating
+ * other instances.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class MultiProviderAuditorProvider implements Provider<Auditor>
+{
+
+ private Collection<Auditor> auditors;
+
+ /**
+ * Creates a provider using existing {@link Auditor} instances.
+ * @param auditor An array of auditors to be used by {@link
MultiProviderAuditor} instances.
+ */
+ public MultiProviderAuditorProvider(Auditor[] auditors)
+ {
+ if (auditors == null || auditors.length == 0)
+ throw new IllegalArgumentException("Auditor array cannot be null or
empty.");
+
+ setAuditors(Arrays.asList(auditors));
+ }
+
+ /**
+ * Creates a provider using providers to create the internal auditors.
+ * @param auditor An array of auditor providers used to create the
internal auditors.
+ */
+ public MultiProviderAuditorProvider(Provider<Auditor>[] providers)
+ {
+ if (providers == null || providers.length == 0)
+ throw new IllegalArgumentException("Prover list cannot be null or
empty.");
+
+ Collection<Auditor> auditors = new ArrayList<Auditor>();
+ for (Provider<Auditor> provider : providers)
+ auditors.add(provider.get());
+
+ setAuditors(auditors);
+ }
+
+ /*
+ * Sets the list of auditors that will be used to construct the
MultiProviderAuditor
+ */
+ private void setAuditors(Collection<Auditor> auditors)
+ {
+ this.auditors = auditors;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Auditor get()
+ {
+ return new MultiProviderAuditor(auditors);
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/NoOpAuditorProvider.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.provider;
+
+import org.nhindirect.common.audit.Auditor;
+import org.nhindirect.common.audit.impl.NoOpAuditor;
+
+import com.google.inject.Provider;
+
+/**
+ * Guice provider for creating {@link NoOpAuditor} instances.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class NoOpAuditorProvider implements Provider<Auditor>
+{
+ /**
+ * Default constructor.
+ */
+ public NoOpAuditorProvider()
+ {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Auditor get()
+ {
+ return new NoOpAuditor();
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/SPIAuditorProvider.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,103 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.audit.provider;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.Vector;
+
+import org.nhindirect.common.audit.Auditor;
+import org.nhindirect.common.audit.impl.MultiProviderAuditor;
+
+import com.google.inject.Provider;
+
+/**
+ * Guice provider for creating {@link Auditor} instances using Java SPI.
If multiple service provider implementation are located, an instance of
+ * each auditor implementation is created and placed in an {@link
MultiProviderAuditor} instance.
+ * @author Greg Meyer
+ * @since 1.0
+ */
+public class SPIAuditorProvider implements Provider<Auditor>
+{
+ private final Auditor implementation;
+
+ /**
+ * Default constructor. Searches for available implementations of the
{@link Auditor} interface using Java SPI (service provider interface).
+ */
+ public SPIAuditorProvider()
+ {
+ this(null);
+ }
+
+ /**
+ * Default constructor. Searches for available implementations of the
{@link Auditor} interface using Java SPI (service provider interface)
+ * using the provided class loader to search for implementations. If the
class loader is null, the Auditor class's loader will be used.
+ */
+ public SPIAuditorProvider(ClassLoader cl)
+ {
+ final ClassLoader cLoader = (cl != null) ? cl :
Auditor.class.getClassLoader();
+
+ final ServiceLoader<Auditor> loader = ServiceLoader.load(Auditor.class,
cLoader);
+
+ Vector<Auditor> implementations;
+
+ Iterator<Auditor> iter = null;
+
+ if (loader != null && (iter = loader.iterator()) != null)
+ {
+ implementations = new Vector<Auditor>();
+ while (iter.hasNext())
+ implementations.add(iter.next());
+
+ if (implementations.size() == 0)
+ implementation = null;
+ else if (implementations.size() == 1)
+ implementation = implementations.firstElement();
+ else
+ implementation = new MultiProviderAuditor(implementations);
+
+ }
+ else
+ implementation = null;
+ }
+
+ /**
+ * Indicates if a service provider implementation is available.
+ * @return True is a service provider implementation is available. False
otherwise.
+ */
+ public boolean isImplementationAvailable()
+ {
+ return implementation != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Auditor get()
+ {
+ if (!isImplementationAvailable())
+ return null;
+
+ return implementation;
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/audit/provider/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,5 @@
+/**
+ * Guide providers for creating {@link Auditor} implementation instances.
+ */
+
+package org.nhindirect.common.audit.provider;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/KeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,72 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto;
+
+import java.security.Key;
+import java.util.Map;
+
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * Interface definition for accessing key store pass phrases. PKCS12
keystores generally have two layers of protection with each being options:
+ * <br>
+ * <ul>
+ * <li>Pass phrase protection for the entire key store.</li>
+ * <li>Pass phrase protection for private keys associated with a public
key</li>
+ * <br>
+ * This interface assumes that all private keys are stores with the same
pass phrase. Pass phrases may stored in a multitude of mediums such as
protected files,
+ * databases, or PKCS11 tokens.
+ * @author Greg Meyer
+ * @since 1.3
+ *
+ */
+public interface KeyStoreProtectionManager
+{
+ /**
+ * Gets the key protecting the key store as a whole.
+ * @return The key protecting the key store as a whole.
+ * @throws CryptoException
+ */
+ public Key getPrivateKeyProtectionKey() throws CryptoException;
+
+ /**
+ * Gets the key protecting private keys in the key store.
+ * @return The key protecting private keys in the key store.
+ * @throws CryptoException
+ */
+ public Key getKeyStoreProtectionKey() throws CryptoException;
+
+ /**
+ * Gets a Map of all keys managed by the token.
+ * @return Returns a map of all keys in the token. The mapping is key
alias to key.
+ * @throws CryptoException
+ */
+ public Map<String, Key> getAllKeys() throws CryptoException;
+
+ /**
+ * Gets a specific key by name.
+ * @param keyName The name of the key to retrieve. Returns null if the
key doesn't exist.
+ * @return They key specified by the name.
+ * @throws CryptoException
+ */
+ public Key getKey(String keyName) throws CryptoException;
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/MutableKeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,113 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto;
+
+import java.security.Key;
+
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * Interface for setting and clearing the secret keys for keystore and
private key protection. This
+ * interface is implemented by stores that allow manipulation of the key
material.
+ * <p>
+ * This interface assumes that key material is generated outside of the
key store manager.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+public interface MutableKeyStoreProtectionManager extends
KeyStoreProtectionManager
+{
+ /**
+ * Sets key used to protect the private key as a Key object.
+ * @param key The key used to protect private keys.
+ * @throws CryptoException
+ */
+ public void setPrivateKeyProtectionKey(Key key) throws CryptoException;
+
+ /**
+ * Sets the key used to protect the private key as a byte array.
+ * @param key The key used to protect private keys.
+ * @throws CryptoException
+ */
+ public void setPrivateKeyProtectionKeyAsBytes(byte[] key) throws
CryptoException;
+
+ /**
+ * Sets the key used to protect the private key as a string. This is
useful when pass phrases
+ * are generated by a plain text tool.
+ * @param key The key used to protect private keys.
+ * @throws CryptoException
+ */
+ public void setPrivateKeyProtectionKeyAsString(String key) throws
CryptoException;
+
+ /**
+ * Clears the key use to protect the private key. Some implementations
require that the
+ * key be cleared before a new value can be set. For deterministic
results, you should always
+ * clear the key before setting a new value.
+ * @throws CryptoException
+ */
+ public void clearPrivateKeyProtectionKey() throws CryptoException;
+
+ /**
+ * Sets key used to protect the key store as a Key object.
+ * @param key The key used to protect the key store.
+ * @throws CryptoException
+ */
+ public void setKeyStoreProtectionKey(Key key) throws CryptoException;
+
+ /**
+ * Sets key used to protect the key store as a byte array.
+ * @param key The key used to protect the key store.
+ * @throws CryptoException
+ */
+ public void setKeyStoreProtectionKeyAsBytes(byte[] key) throws
CryptoException;
+
+ /**
+ * Sets key used to protect the key store as a string. This is useful
when pass phrases
+ * are generated by a plain text tool.
+ * @param key The key used to protect the key store.
+ * @throws CryptoException
+ */
+ public void setKeyStoreProtectionKeyAsString(String key) throws
CryptoException;
+
+ /**
+ * Clears the key use to protect the key store. Some implementations
require that the
+ * key be cleared before a new value can be set. For deterministic
results, you should always
+ * clear the key before setting a new value.
+ * @throws CryptoException
+ */
+ public void clearKeyStoreProtectionKey() throws CryptoException;
+
+ /**
+ * Generic method to set an arbitrary key.
+ * @param alias Alias of the key that will be set.
+ * @param key The key that will be set.
+ * @throws CryptoException
+ */
+ public void setKey(String alias, Key key) throws CryptoException;
+
+ /**
+ * Generic method to clear an arbitrary key.
+ * @param alias Alias of the key that will be cleared.
+ * @throws CryptoException
+ */
+ public void clearKey(String alias) throws CryptoException;
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/PKCS11Credential.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,33 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto;
+
+/**
+ * Interface to access credentials for "logging into" a PKCS11 token.
Credentials may be stored in or on a variety of media including
+ * protected files, databases, or secure sockets.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+public interface PKCS11Credential
+{
+ public char[] getPIN();
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/exceptions/CryptoException.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,67 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto.exceptions;
+
+///CLOVER:OFF
+/**
+ * Generic cryptography exception thrown when perform crypto operations.
+ * @author Greg Meyer
+ * @since 1.3
+ *
+ */
+public class CryptoException extends Exception
+{
+
+ private static final long serialVersionUID = -213341487580684180L;
+
+ /**
+ * {@inheritDoc}
+ */
+ public CryptoException()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CryptoException(String msg)
+ {
+ super(msg);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CryptoException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CryptoException(Throwable t)
+ {
+ super(t);
+ }
+}
+///CLOVER:OFF
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/exceptions/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,26 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+/**
+ * Exception classes for crypto operations.
+ */
+
+package org.nhindirect.common.crypto.exceptions;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/AbstractPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,541 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.PKCS11Credential;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * Abstract base class for accessing key store pass phrases from a PKCS11
token. Concrete implementations
+ * define methods for logging into the token.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+public abstract class AbstractPKCS11TokenKeyStoreProtectionManager
implements MutableKeyStoreProtectionManager
+{
+
+ private static final Log LOGGER =
LogFactory.getFactory().getInstance(AbstractPKCS11TokenKeyStoreProtectionManager.class);
+
+ protected static final String SUNPKCS11_KEYSTORE_PROVIDER_NAME
= "sun.security.pkcs11.SunPKCS11";
+ protected static final String DEFAULT_KESTORE_TYPE = "PKCS11";
+
+ protected PKCS11Credential credential;
+ protected String keyStorePassPhraseAlias;
+ protected String privateKeyPassPhraseAlias;
+ protected KeyStore ks;
+ protected String keyStoreType;
+ protected String keyStoreProviderName;
+ protected String pcks11ConfigFile;
+ protected InputStream keyStoreSource;
+
+ /**
+ * Empty constructor.
+ * @throws CryptoException
+ */
+ public AbstractPKCS11TokenKeyStoreProtectionManager() throws
CryptoException
+ {
+ this.credential = null;
+ this.keyStorePassPhraseAlias = "";
+ this.privateKeyPassPhraseAlias = "";
+ this.keyStoreType = DEFAULT_KESTORE_TYPE;
+ this.keyStoreProviderName = "";
+ this.pcks11ConfigFile = "";
+ this.keyStoreSource = null;
+ }
+
+ /**
+ * Constructor that takes a credential interface for logging into the
token.
+ * @param credential The credential used to log into the token.
+ * @param keyStorePassPhraseAlias The alias name of the key store key in
the PKCS11 token.
+ * @param privateKeyPassPhraseAlias The alias name of the private key
protection key in the PKCS11 token.
+ * @throws CryptoException
+ */
+ public AbstractPKCS11TokenKeyStoreProtectionManager(PKCS11Credential
credential, String keyStorePassPhraseAlias, String
privateKeyPassPhraseAlias) throws CryptoException
+ {
+ this.credential = credential;
+ this.keyStorePassPhraseAlias = keyStorePassPhraseAlias;
+ this.privateKeyPassPhraseAlias = privateKeyPassPhraseAlias;
+ this.keyStoreType = DEFAULT_KESTORE_TYPE;
+ this.keyStoreProviderName = "";
+ this.pcks11ConfigFile = "";
+ this.keyStoreSource = null;
+
+ initTokenStore();
+ }
+
+ @SuppressWarnings("restriction")
+ protected void loadProvider() throws CryptoException
+ {
+ try
+ {
+ // first see if we need to add a PKCS11 provider or custom provider
+
+ if (!StringUtils.isEmpty(this.keyStoreProviderName))
+ {
+ if (this.keyStoreProviderName.equals(SUNPKCS11_KEYSTORE_PROVIDER_NAME))
+ {
+ // we want to add a SunPKCS11 provider...
+ // this provider requires a config file
+ if (StringUtils.isEmpty(this.pcks11ConfigFile))
+ throw new IllegalStateException("SunPKCS11 providers require a
configuration file. There is not one set.");
+
+ // check and see if this is one of the same providers that is already
loaded
+ final InputStream inStream = FileUtils.openInputStream(new
File(this.pcks11ConfigFile));
+
+ final Properties props = new Properties();
+ props.load(inStream);
+ IOUtils.closeQuietly(inStream);
+
+ boolean providerFound = false;
+
+ final String requestedName = props.getProperty("name");
+
+ // check if this provider exists
+ if (!StringUtils.isEmpty(requestedName) &&
Security.getProvider(requestedName) != null)
+ providerFound = true;
+
+ if (!providerFound)
+ Security.addProvider(new
sun.security.pkcs11.SunPKCS11(this.pcks11ConfigFile));
+ }
+ else
+ {
+ // create the new provider
+ final Class<?> provider =
this.getClass().getClassLoader().loadClass(this.keyStoreProviderName);
+
+ // check if the provider is already loaded
+ boolean providerFound = false;
+ for (Provider existingProv : Security.getProviders())
+ {
+ if (existingProv.getClass().equals(provider))
+ {
+ providerFound = true;
+ break;
+ }
+ }
+
+ if (!providerFound)
+ Security.addProvider((Provider)provider.newInstance());
+
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error loading PKCS11 provder", e);
+ }
+ }
+
+ /**
+ * Sets the credential used to log into the token.
+ * @param credential The credential used to log into the token.
+ */
+ public void setCredential(PKCS11Credential credential)
+ {
+ this.credential = credential;
+ }
+
+ /**
+ * Sets the alias name of the key store key in the PKCS11 token.
+ * @param keyStorePassPhraseAlias The alias name of the key store key in
the PKCS11 token.
+ */
+ public void setKeyStorePassPhraseAlias(String keyStorePassPhraseAlias)
+ {
+ this.keyStorePassPhraseAlias = keyStorePassPhraseAlias;
+ }
+
+ /**
+ * Sets the alias name of the private key protection key in the PKCS11
token.
+ * @param privateKeyPassPhraseAlias the alias name of the private key
protection key in the PKCS11 token.
+ */
+ public void setPrivateKeyPassPhraseAlias(String privateKeyPassPhraseAlias)
+ {
+ this.privateKeyPassPhraseAlias = privateKeyPassPhraseAlias;
+ }
+
+ public void setKeyStoreType(String keyStoreType)
+ {
+ this.keyStoreType = keyStoreType;
+ }
+
+ public void setKeyStoreSource(InputStream keyStoreSource)
+ {
+ this.keyStoreSource = keyStoreSource;
+ }
+
+ public void setKeyStoreSourceAsString(String keyStoreSource)
+ {
+ try
+ {
+ this.keyStoreSource = new
ByteArrayInputStream(keyStoreSource.getBytes("UTF-8"));
+ }
+ catch (Exception e)
+ {
+ /* do quietly, no-op */
+ }
+ }
+
+ public void setKeyStoreProviderName(String keyStoreProviderName)
+ {
+ this.keyStoreProviderName = keyStoreProviderName;
+ }
+
+ public void setPcks11ConfigFile(String pcks11ConfigFile)
+ {
+ this.pcks11ConfigFile = pcks11ConfigFile;
+ }
+
+ /**
+ * Initializes access to the token. This is implementation specific and
may require user interaction.
+ * @throws CryptoException
+ */
+ public abstract void initTokenStore() throws CryptoException;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized Map<String, Key> getAllKeys() throws CryptoException
+ {
+ final Map<String, Key> keys = new HashMap<String, Key>();
+
+ try
+ {
+ final Enumeration<String> aliases = ks.aliases();
+ while (aliases.hasMoreElements())
+ {
+ final String alias = aliases.nextElement();
+ if (ks.isKeyEntry(alias))
+ {
+ try
+ {
+ final Key key = ks.getKey(alias, null);
+ // make sure it's a secret key
+
+ if (key instanceof SecretKey)
+ {
+ keys.put(alias, key);
+ }
+ }
+ catch (Exception e)
+ {
+ // no-op, this might be a key that we don't care about
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error extracting private key protection from
PKCS11 token", e);
+ }
+
+ return keys;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getKey(String keyName) throws CryptoException
+ {
+ return safeGetKeyWithRetry(keyName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getPrivateKeyProtectionKey() throws CryptoException
+ {
+ return safeGetKeyWithRetry(privateKeyPassPhraseAlias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getKeyStoreProtectionKey() throws CryptoException
+ {
+ return safeGetKeyWithRetry(keyStorePassPhraseAlias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrivateKeyProtectionKey(Key key) throws CryptoException
+ {
+ safeSetKeyWithRetry(privateKeyPassPhraseAlias, key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrivateKeyProtectionKeyAsBytes(byte[] key) throws
CryptoException
+ {
+ try
+ {
+ final Key keySpec = new SecretKeySpec(key, "");
+ safeSetKeyWithRetry(privateKeyPassPhraseAlias, keySpec);
+ }
+ catch (CryptoException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error storing key store protection into
PKCS11 token", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrivateKeyProtectionKeyAsString(String key) throws
CryptoException
+ {
+ try
+ {
+ final Key keySpec = new SecretKeySpec(key.getBytes(), "");
+ safeSetKeyWithRetry(privateKeyPassPhraseAlias, keySpec);
+ }
+ catch (CryptoException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error storing key store protection into
PKCS11 token", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearPrivateKeyProtectionKey() throws CryptoException
+ {
+ safeDeleteKeyWithRetry(privateKeyPassPhraseAlias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setKeyStoreProtectionKey(Key key) throws CryptoException
+ {
+ safeSetKeyWithRetry(keyStorePassPhraseAlias, key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setKeyStoreProtectionKeyAsBytes(byte[] key) throws
CryptoException
+ {
+ try
+ {
+ final Key keySpec = new SecretKeySpec(key, "");
+ safeSetKeyWithRetry(keyStorePassPhraseAlias, keySpec);
+ }
+ catch (CryptoException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error storing key store protection into
PKCS11 token", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setKeyStoreProtectionKeyAsString(String key) throws
CryptoException
+ {
+ try
+ {
+ final Key keySpec = new SecretKeySpec(key.getBytes(), "");
+ safeSetKeyWithRetry(keyStorePassPhraseAlias, keySpec);
+ }
+ catch (CryptoException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error storing key store protection into
PKCS11 token", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearKeyStoreProtectionKey() throws CryptoException
+ {
+ this.safeDeleteKeyWithRetry(keyStorePassPhraseAlias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setKey(String alias, Key key) throws CryptoException
+ {
+ safeSetKeyWithRetry(alias, key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearKey(String alias) throws CryptoException
+ {
+ // make sure the key exists first
+ if (this.getKey(alias) != null)
+ safeDeleteKeyWithRetry(alias);
+ }
+
+ protected synchronized void safeSetKeyWithRetry(String alias, Key key)
throws CryptoException
+ {
+ boolean reloadAndRetry = false;
+
+ try
+ {
+ ks.setKeyEntry(alias, key, null, null);
+ }
+ catch (Exception e)
+ {
+ LOGGER.warn("Could not set key entry on first attemp. Will attempt to
reload the key store and try again");
+ reloadAndRetry = true;
+ }
+
+ if (reloadAndRetry)
+ {
+ this.reloadKeyStore();
+
+ try
+ {
+ ks.setKeyEntry(alias, key, null, null);
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error setting key in PKCS11 token", e);
+ }
+ }
+ }
+
+ protected synchronized void safeDeleteKeyWithRetry(String alias) throws
CryptoException
+ {
+ boolean reloadAndRetry = false;
+
+ try
+ {
+ ks.deleteEntry(alias);
+ }
+ catch (Exception e)
+ {
+ LOGGER.warn("Could not delete key entry on first attemp. Will attempt
to reload the key store and try again");
+ reloadAndRetry = true;
+ }
+
+ if (reloadAndRetry)
+ {
+ this.reloadKeyStore();
+
+ try
+ {
+ ks.deleteEntry(alias);
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error deleting key from PKCS11 token", e);
+ }
+ }
+ }
+
+ protected synchronized Key safeGetKeyWithRetry(String alias) throws
CryptoException
+ {
+ boolean reloadAndRetry = false;
+
+ try
+ {
+ return ks.getKey(alias, null);
+ }
+ catch (Exception e)
+ {
+ LOGGER.warn("Could not get key entry on first attemp. Will attempt to
reload the key store and try again");
+ reloadAndRetry = true;
+ }
+
+ if (reloadAndRetry)
+ {
+ this.reloadKeyStore();
+
+ try
+ {
+ return ks.getKey(alias, null);
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error getting key from PKCS11 token", e);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * In some cases, the connection to the underlying key store may become
disconnected and the keystore needs to be reloaded
+ */
+ protected void reloadKeyStore() throws CryptoException
+ {
+ // close the key store and reload it
+ ks = null;
+
+ initTokenStore();
+ }
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedKeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,135 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+package org.nhindirect.common.crypto.impl;
+
+import java.security.Key;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.nhindirect.common.crypto.KeyStoreProtectionManager;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * Implementation of a key store manager where the protection keys are
provided as injected parameters. This class is useful if the
+ * pass phrases or keys are stored in configuration files and can be
provided as declarative config statements.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+public class BootstrappedKeyStoreProtectionManager implements
KeyStoreProtectionManager
+{
+ protected Key keyStoreProtectionKey;
+ protected Key privateKeyProtectionKey;
+
+ /**
+ * Empty constructore
+ */
+ public BootstrappedKeyStoreProtectionManager ()
+ {
+
+ }
+
+ /**
+ * Constructs a manager by providing the protection keys as strings.
+ * @param keyStoreProtectionKey The pass phrase that protects the key
store as a whole.
+ * @param privateKeyProtectionKey The pass phrase that protects the
private keys in the key store.
+ */
+ public BootstrappedKeyStoreProtectionManager (String
keyStoreProtectionKey, String privateKeyProtectionKey)
+ {
+ setKeyStoreProtectionKey(keyStoreProtectionKey);
+ setPrivateKeyProtectionKey(privateKeyProtectionKey);
+ }
+
+ /**
+ * Sets the pass phrase that protects the key store as a whole as a byte
array.
+ * @param keyStoreProtectionKey The pass phrase that protects the key
store as a whole as a byte array.
+ */
+ public void setKeyStoreProtectionKey(byte[] keyStoreProtectionKey)
+ {
+ this.keyStoreProtectionKey = new
SecretKeySpec(keyStoreProtectionKey, "");
+ }
+
+ /**
+ * Sets the pass phrase that protects the key store as a whole as a
String.
+ * @param keyStoreProtectionKey The pass phrase that protects the key
store as a whole as a String.
+ */
+ public void setKeyStoreProtectionKey(String keyStoreProtectionKey)
+ {
+ this.keyStoreProtectionKey = new
SecretKeySpec(keyStoreProtectionKey.getBytes(), "");
+ }
+
+ /**
+ * Sets the pass phrase that protects the private keys in the key store
as a byte array.
+ * @param privateKeyProtectionKey The pass phrase that protects the
private keys in the key store as a byte array.
+ */
+ public void setPrivateKeyProtectionKey(byte[] privateKeyProtectionKey)
+ {
+ this.privateKeyProtectionKey = new
SecretKeySpec(privateKeyProtectionKey, "");
+ }
+
+ /**
+ * Sets the pass phrase that protects the private keys in the key store
as a String.
+ * @param privateKeyProtectionKey The pass phrase that protects the
private keys in the key store as a String.
+ */
+ public void setPrivateKeyProtectionKey(String privateKeyProtectionKey)
+ {
+ this.privateKeyProtectionKey = new
SecretKeySpec(privateKeyProtectionKey.getBytes(), "");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getPrivateKeyProtectionKey() throws CryptoException
+ {
+ return privateKeyProtectionKey;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getKeyStoreProtectionKey() throws CryptoException
+ {
+ return keyStoreProtectionKey;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<String, Key> getAllKeys() throws CryptoException
+ {
+ final Map<String, Key> keys = new HashMap<String, Key>();
+
+ keys.put("PrivKeyProtKey", getPrivateKeyProtectionKey());
+ keys.put("KeyStoreProtKey", getKeyStoreProtectionKey());
+
+ return keys;
+ }
+
+ @Override
+ public Key getKey(String keyName) throws CryptoException
+ {
+ return null;
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedPKCS11Credential.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,70 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto.impl;
+
+import org.nhindirect.common.crypto.PKCS11Credential;
+
+/**
+ * Implementation of a PKCS11 credential where the pin is provided as an
injected parameter. This class is useful if the
+ * pin is stored in configuration files and can be provided as declarative
config statements.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+public class BootstrappedPKCS11Credential implements PKCS11Credential
+{
+ protected String pin;
+
+ /**
+ * Empty constructor
+ */
+ public BootstrappedPKCS11Credential()
+ {
+
+ }
+
+ /**
+ * Constructor
+ * @param pin The PKCS11 pin used to login to the token
+ */
+ public BootstrappedPKCS11Credential(String pin)
+ {
+ this.pin = pin;
+ }
+
+ /**
+ * Sets the pin
+ * @param pin The PKCS11 pin used to login to the tokens
+ */
+ public void setPin(String pin)
+ {
+ this.pin = pin;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public char[] getPIN()
+ {
+ return pin.toCharArray();
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/DynamicPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,122 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto.impl;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.commons.lang.StringUtils;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * A more dynamic implementation than the
StaticPKCS11TokenKeyStoreProtectionManager that allows for swap-able tokens
and plug-able methods
+ * for different logging into the token as described by the {@link
javax.security.auth.callback.CallbackHandler} class. Instances
+ * must provide a CallbackHander implementation for providing credential
information.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+/// CLOVER:OFF
+public class DynamicPKCS11TokenKeyStoreProtectionManager extends
AbstractPKCS11TokenKeyStoreProtectionManager
+{
+ protected CallbackHandler handler;
+ protected KeyStore.Builder keyStoreBuilder;
+
+ /**
+ * Default Constructor
+ * @throws CryptoException
+ */
+ public DynamicPKCS11TokenKeyStoreProtectionManager() throws
CryptoException
+ {
+ super();
+ }
+
+ /**
+ * Constructs the store with the aliases and a callback handler.
+ * @param keyStorePassPhraseAlias The alias name of the key store key in
the PKCS11 token.
+ * @param privateKeyPassPhraseAlias The alias name of the private key
protection key in the PKCS11 token.
+ * @param handler A callback handler implementation used to obtain
credential information.
+ * @throws CryptoException
+ */
+ public DynamicPKCS11TokenKeyStoreProtectionManager(String
keyStorePassPhraseAlias, String privateKeyPassPhraseAlias, CallbackHandler
handler) throws CryptoException
+ {
+ this(keyStorePassPhraseAlias, keyStorePassPhraseAlias, handler, null,
null);
+ }
+
+ public DynamicPKCS11TokenKeyStoreProtectionManager(String
keyStorePassPhraseAlias, String privateKeyPassPhraseAlias, CallbackHandler
handler,
+ String keyStoreType, InputStream inputStream) throws CryptoException
+ {
+ this.keyStorePassPhraseAlias = keyStorePassPhraseAlias;
+ this.privateKeyPassPhraseAlias = privateKeyPassPhraseAlias;
+ this.handler = handler;
+ if (!StringUtils.isEmpty(keyStoreType))
+ this.keyStoreType = keyStoreType;
+ else
+ this.keyStoreType = DEFAULT_KESTORE_TYPE;
+
+ configureKeyStoreBuilder();
+
+ initTokenStore();
+ }
+
+ /**
+ * Sets the callback handler used obtain credential information.
+ * @param handler The callback handler used obtain credential information.
+ */
+ public void setCallbackHandler(CallbackHandler handler)
+ {
+ this.handler = handler;
+
+ configureKeyStoreBuilder();
+ }
+
+ /**
+ * Configures the key store builder for creating token stores.
+ */
+ protected void configureKeyStoreBuilder()
+ {
+ final KeyStore.CallbackHandlerProtection chp =
+ new KeyStore.CallbackHandlerProtection(handler);
+
+ keyStoreBuilder = KeyStore.Builder.newInstance(keyStoreType, null, chp);
+ }
+
+ /**
+ * {@inheritDocs}
+ */
+ public void initTokenStore() throws CryptoException
+ {
+ try
+ {
+ loadProvider();
+
+ ks = keyStoreBuilder.getKeyStore();
+ ks.load(keyStoreSource, null);
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error initializing PKCS11 token", e);
+ }
+ }
+}
+/// CLOVER:ON
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/StaticCachedPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,94 @@
+package org.nhindirect.common.crypto.impl;
+
+import java.security.Key;
+import java.security.KeyStore;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.nhindirect.common.crypto.PKCS11Credential;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * This implementations uses the same login process as the {@link
StaticPKCS11TokenKeyStoreProtectionManager}, however the
+ * keystore and private key protection keys are loaded into the manager at
init time and cached in the class. The advantage
+ * is that multiple trips do not have to be made to the HSM to get the
secret keys per certificate operation. They disadvantage
+ * is that secret keys or cached in process memory.
+ * <p>
+ * This class is also a generic band aid for systems that get disconnected
from their HSMs due to policy and technical reasons. These
+ * systems need access to the secret keys even after they are disconnected.
+ * @author Greg Meyer
+ * @since 1.4.1
+ */
+public class StaticCachedPKCS11TokenKeyStoreProtectionManager extends
StaticPKCS11TokenKeyStoreProtectionManager
+{
+ private Key keystoreProtectionKey;
+ private Key privateKeyProtectionKey;
+
+ /**
+ * Empty constructor
+ * @throws CryptoException
+ */
+ public StaticCachedPKCS11TokenKeyStoreProtectionManager() throws
CryptoException
+ {
+ super();
+ }
+
+ /**
+ * Constructs the store with a credential manager and aliases.
+ * @param credential The credentials to log into the store.
+ * @param keyStorePassPhraseAlias The alias name of the key store key in
the PKCS11 token.
+ * @param privateKeyPassPhraseAlias The alias name of the private key
protection key in the PKCS11 token.
+ * @throws CryptoException
+ */
+ public StaticCachedPKCS11TokenKeyStoreProtectionManager(PKCS11Credential
credential, String keyStorePassPhraseAlias, String
privateKeyPassPhraseAlias) throws CryptoException
+ {
+ super(credential, keyStorePassPhraseAlias, privateKeyPassPhraseAlias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void initTokenStore() throws CryptoException
+ {
+ loadProvider();
+
+ try
+ {
+ ks = KeyStore.getInstance(keyStoreType);
+ ks.load(keyStoreSource, credential.getPIN());
+
+ // preload the 2 secret keys
+ keystoreProtectionKey = this.getKey(keyStorePassPhraseAlias);
+ privateKeyProtectionKey = this.getKey(privateKeyPassPhraseAlias);
+
+ // some HSMs only store references to the keys in these objects and
+ // and still have to go back to the HSM to pull the actual key data
+ // create a key object from the encoded data
+ keystoreProtectionKey = new
SecretKeySpec(keystoreProtectionKey.getEncoded(), "");
+ privateKeyProtectionKey = new
SecretKeySpec(privateKeyProtectionKey.getEncoded(), "");
+
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error initializing PKCS11 token", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getPrivateKeyProtectionKey() throws CryptoException
+ {
+ return privateKeyProtectionKey;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getKeyStoreProtectionKey() throws CryptoException
+ {
+ return keystoreProtectionKey;
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/StaticPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,77 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.crypto.impl;
+
+import java.security.KeyStore;
+
+import org.nhindirect.common.crypto.PKCS11Credential;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+
+/**
+ * Implementation of PKCS11 token store that generally does not get
detached from the system. Credentials are accessed via a PKCS11Credential
implementation.
+ * @author Greg Meyer
+ * @since 1.3
+ */
+/// CLOVER:OFF
+public class StaticPKCS11TokenKeyStoreProtectionManager extends
AbstractPKCS11TokenKeyStoreProtectionManager
+{
+
+ /**
+ * Empty constructor
+ * @throws CryptoException
+ */
+ public StaticPKCS11TokenKeyStoreProtectionManager() throws CryptoException
+ {
+ super();
+ }
+
+ /**
+ * Constructs the store with a credential manager and aliases.
+ * @param credential The credentials to log into the store.
+ * @param keyStorePassPhraseAlias The alias name of the key store key in
the PKCS11 token.
+ * @param privateKeyPassPhraseAlias The alias name of the private key
protection key in the PKCS11 token.
+ * @throws CryptoException
+ */
+ public StaticPKCS11TokenKeyStoreProtectionManager(PKCS11Credential
credential, String keyStorePassPhraseAlias, String
privateKeyPassPhraseAlias) throws CryptoException
+ {
+ super(credential, keyStorePassPhraseAlias, privateKeyPassPhraseAlias);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void initTokenStore() throws CryptoException
+ {
+ loadProvider();
+
+ try
+ {
+ ks = KeyStore.getInstance(keyStoreType);
+ ks.load(keyStoreSource, credential.getPIN());
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error initializing PKCS11 token", e);
+ }
+ }
+}
+/// CLOVER:ON
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/impl/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,26 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+/**
+ * Implementation specific classes of crypto interfaces.
+ */
+
+package org.nhindirect.common.crypto.impl;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/package-info.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,26 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+/**
+ * Interfaces an utilities for general cryptography operations.
+ */
+
+package org.nhindirect.common.crypto;
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/CommandLineTokenLoginCallback.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,55 @@
+package org.nhindirect.common.crypto.tools;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class CommandLineTokenLoginCallback implements CallbackHandler
+{
+ public Object waitObject = new Object();
+
+ public boolean loginSuccessful = false;
+
+ public CommandLineTokenLoginCallback()
+ {
+ }
+
+ @Override
+ public synchronized void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException
+ {
+ for (Callback callback : callbacks)
+ {
+ if (callback instanceof PasswordCallback)
+ {
+
+ final Console cons = System.console();
+ char[] passwd = null;
+ if (cons != null)
+ {
+ passwd = cons.readPassword("[%s]", "Enter hardware token
password: ");
+ java.util.Arrays.fill(passwd, ' ');
+ }
+ else
+ {
+ System.out.print("Enter hardware token password: ");
+ final BufferedReader reader = new BufferedReader(new
InputStreamReader(
+ System.in));
+ passwd = reader.readLine().toCharArray();
+ }
+
+
+ ((PasswordCallback)callback).setPassword(passwd);
+
+ }
+ }
+
+ this.notifyAll();
+ }
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManager.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,223 @@
+package org.nhindirect.common.crypto.tools;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.Console;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+import org.nhindirect.common.crypto.impl.BootstrappedPKCS11Credential;
+import
org.nhindirect.common.crypto.impl.StaticPKCS11TokenKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.tools.commands.PKCS11Commands;
+import org.nhindirect.common.tooling.Commands;
+
+///CLOVER:OFF
+public class PKCS11SecretKeyManager
+{
+
+ private static boolean exitOnEndCommands = true;
+ private static String keyStoreType = null;
+ private static String providerName = null;
+ private static String keyStoreSource = null;
+
+ private final Commands commands;
+
+ protected static String pkcs11ProviderCfg = null;
+ protected static String keyStoreConfigFile = null;
+
+ public static void main(String[] argv)
+ {
+ String[] passArgs = null;
+
+
+ // need to check if there is a configuration for the PKCS11
+ // provider... if not, assume the JVM has already been configured for one
+ if (argv.length > 0)
+ {
+
+ // Check parameters
+ for (int i = 0; i < argv.length; i++)
+ {
+ String arg = argv[i];
+
+ // Options
+ if (!arg.startsWith("-"))
+ {
+ System.err.println("Error: Unexpected argument [" + arg
+ "]\n");
+ printUsage();
+ System.exit(-1);
+ }
+ else if (arg.equalsIgnoreCase("-pkcscfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing pkcs config file");
+ System.exit(-1);
+ }
+
+ pkcs11ProviderCfg = argv[++i];
+
+ }
+ else if (arg.equals("-keyStoreCfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing keystore config
file");
+ System.exit(-1);
+ }
+ keyStoreConfigFile = argv[++i];
+ }
+ else if (arg.equals("-help"))
+ {
+ printUsage();
+ System.exit(-1);
+ }
+ else
+ {
+ System.err.println("Error: Unknown argument " + arg
+ "\n");
+ printUsage();
+ System.exit(-1);
+ }
+ }
+ }
+
+ if (keyStoreConfigFile != null)
+ {
+ try
+ {
+ // get additional properties
+ final InputStream inStream = FileUtils.openInputStream(new
File(keyStoreConfigFile));
+
+ final Properties props = new Properties();
+ props.load(inStream);
+
+ keyStoreType = props.getProperty("keyStoreType");
+ providerName = props.getProperty("keyStoreProviderName");
+ keyStoreSource = props.getProperty("keyStoreSource");
+ }
+ catch (IOException e)
+ {
+ System.err.println("Error reading keystore config file to
properties: " + e.getMessage());
+ System.exit(-1);
+ }
+ }
+
+ MutableKeyStoreProtectionManager mgr = null;
+ // need to login
+ try
+ {
+ mgr = tokenLogin();
+ }
+ catch (CryptoException e)
+ {
+
+ System.out.println("Failed to login to hardware token: " +
e.getMessage());
+ System.exit(-1);
+ }
+ final PKCS11SecretKeyManager mgmt = new PKCS11SecretKeyManager(mgr);
+
+ boolean runCommand = false;
+
+ if (mgmt != null)
+ {
+ runCommand = mgmt.run(passArgs);
+ }
+
+ if (exitOnEndCommands)
+ System.exit(runCommand ? 0 : -1);
+ }
+
+ public boolean run(String[] args)
+ {
+ if (args != null && args.length > 0)
+ {
+ return commands.run(args);
+ }
+
+ commands.runInteractive();
+ System.out.println("Shutting Down Configuration Manager Console");
+ return true;
+ }
+
+ /*
+ * Print program usage.
+ */
+ private static void printUsage()
+ {
+ StringBuffer use = new StringBuffer();
+ use.append("Usage:\n");
+ use.append("java PKCS11SecretKeyManager (options)...\n\n");
+ use.append("options:\n");
+ use.append("-pkcscfg PKCS11 Config File Optional location for
the PKCS11 provider configuration. If this is not" +
+ " set, then it is assumed that the JVM has already been
configured to support your PKCS11 token.\n");
+ use.append(" Default: \"\"\n\n");
+
+ System.err.println(use);
+ }
+
+ public static MutableKeyStoreProtectionManager tokenLogin() throws
CryptoException
+ {
+ try
+ {
+
+ final Console cons = null;//System.console();
+ char[] passwd = null;
+ if (cons != null)
+ {
+ passwd = cons.readPassword("[%s]", "Enter hardware token password: ");
+ java.util.Arrays.fill(passwd, ' ');
+ }
+ else
+ {
+ System.out.print("Enter hardware token password: ");
+ final BufferedReader reader = new BufferedReader(new
InputStreamReader(
+ System.in));
+ passwd = reader.readLine().toCharArray();
+ }
+
+ final BootstrappedPKCS11Credential cred = new
BootstrappedPKCS11Credential(new String(passwd));
+ final StaticPKCS11TokenKeyStoreProtectionManager loginMgr = new
StaticPKCS11TokenKeyStoreProtectionManager();
+ loginMgr.setCredential(cred);
+ loginMgr.setKeyStoreProviderName(providerName);
+
+ if (!StringUtils.isEmpty(keyStoreType))
+ loginMgr.setKeyStoreType(keyStoreType);
+
+ if (!StringUtils.isEmpty(keyStoreSource))
+ {
+ InputStream str = new ByteArrayInputStream(keyStoreSource.getBytes());
+ loginMgr.setKeyStoreSource(str);
+ }
+
+ if (!StringUtils.isEmpty(pkcs11ProviderCfg))
+ loginMgr.setPcks11ConfigFile(pkcs11ProviderCfg);
+
+ loginMgr.initTokenStore();
+
+ return loginMgr;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Error getting password.", e);
+ }
+
+ }
+
+ public PKCS11SecretKeyManager(MutableKeyStoreProtectionManager mgr)
+ {
+ commands = new Commands("PKCS11 Secret Key Management Console");
+ commands.register(new PKCS11Commands(mgr));
+ }
+ public static void setExitOnEndCommands(boolean exit)
+ {
+ exitOnEndCommands = exit;
+ }
+}
+///CLOVER:ON
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManagerUI.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,456 @@
+package org.nhindirect.common.crypto.tools;
+
+import java.awt.AWTEvent;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GraphicsEnvironment;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.DefaultTableModel;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+import
org.nhindirect.common.crypto.impl.DynamicPKCS11TokenKeyStoreProtectionManager;
+
+///CLOVER:OFF
+public class PKCS11SecretKeyManagerUI extends JFrame
+{
+
+ private static final long serialVersionUID = 4851276510546674236L;
+
+ protected static String pkcs11ProviderCfg = null;
+ protected static String keyStoreConfigFile = null;
+
+ protected static MutableKeyStoreProtectionManager mgr = null;
+
+ private static String keyStoreType = null;
+ private static String providerName = null;
+ private static String keyStoreSource = null;
+
+ protected JTable keyDataTable;
+ protected JButton removeKeyButton;
+ protected JButton addAESKeyButton;
+ protected JButton addGenericKeyButton;
+ protected DefaultTableModel keyDataModel;
+ protected JButton quitButton;
+
+
+ public static void main(String[] argv)
+ {
+ // need to check if there is a configuration for the PKCS11
+ // provider... if not, assume the JVM has already been configured for one
+ if (argv.length > 0)
+ {
+
+ // Check parameters
+ for (int i = 0; i < argv.length; i++)
+ {
+ String arg = argv[i];
+
+ // Options
+ if (!arg.startsWith("-"))
+ {
+ System.err.println("Error: Unexpected argument [" + arg
+ "]\n");
+ printUsage();
+ System.exit(-1);
+ }
+ else if (arg.equalsIgnoreCase("-pkcscfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing pkcs config file");
+ System.exit(-1);
+ }
+
+ pkcs11ProviderCfg = argv[++i];
+
+ }
+ else if (arg.equals("-keyStoreCfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing keystore config
file");
+ System.exit(-1);
+ }
+ keyStoreConfigFile = argv[++i];
+ }
+ else if (arg.equals("-help"))
+ {
+ printUsage();
+ System.exit(-1);
+ }
+ else
+ {
+ System.err.println("Error: Unknown argument " + arg
+ "\n");
+ printUsage();
+ System.exit(-1);
+ }
+ }
+ }
+
+ if (keyStoreConfigFile != null)
+ {
+ try
+ {
+ // get additional properties
+ final InputStream inStream = FileUtils.openInputStream(new
File(keyStoreConfigFile));
+
+ final Properties props = new Properties();
+ props.load(inStream);
+
+ keyStoreType = props.getProperty("keyStoreType");
+ providerName = props.getProperty("keyStoreProviderName");
+ keyStoreSource = props.getProperty("keyStoreSource");
+ }
+ catch (IOException e)
+ {
+ System.err.println("Error reading keystore config file to
properties: " + e.getMessage());
+ System.exit(-1);
+ }
+ }
+
+ // need to login
+ try
+ {
+ mgr = tokenLogin();
+ }
+ catch (CryptoException e)
+ {
+ JOptionPane.showMessageDialog(null, "Failed to login to hardware
token: " + e.getMessage(), "Token Login Failure",
+ JOptionPane.ERROR_MESSAGE);
+ System.exit(-1);
+ }
+ final PKCS11SecretKeyManagerUI hi = new PKCS11SecretKeyManagerUI();
+ hi.setVisible(true);
+ }
+
+ /*
+ * Print program usage.
+ */
+ private static void printUsage()
+ {
+ StringBuffer use = new StringBuffer();
+ use.append("Usage:\n");
+ use.append("java PKCS11SecretKeyManagerUI (options)...\n\n");
+ use.append("options:\n");
+ use.append("-pkcscfg PKCS11 Config File Optional location for
the PKCS11 provider configuration. If this is not" +
+ " set, then it is assumed that the JVM has already been
configured to support your PKCS11 token.\n");
+ use.append(" Default: \"\"\n\n");
+
+ System.err.println(use);
+ }
+
+ public static MutableKeyStoreProtectionManager tokenLogin() throws
CryptoException
+ {
+
+ TokenLoginCallback login = new TokenLoginCallback();
+
+ final DynamicPKCS11TokenKeyStoreProtectionManager loginMgr = new
DynamicPKCS11TokenKeyStoreProtectionManager();
+
+ loginMgr.setKeyStoreProviderName(providerName);
+
+ if (!StringUtils.isEmpty(keyStoreType))
+ loginMgr.setKeyStoreType(keyStoreType);
+
+ if (!StringUtils.isEmpty(keyStoreSource))
+ {
+ InputStream str = new ByteArrayInputStream(keyStoreSource.getBytes());
+ loginMgr.setKeyStoreSource(str);
+ }
+
+ if (!StringUtils.isEmpty(pkcs11ProviderCfg))
+ loginMgr.setPcks11ConfigFile(pkcs11ProviderCfg);
+
+ loginMgr.setCallbackHandler(login);
+
+ loginMgr.initTokenStore();
+
+ return loginMgr;
+ }
+
+ public PKCS11SecretKeyManagerUI()
+ {
+ super("DirectProject PKCS11 Secret Key Manager");
+ setDefaultLookAndFeelDecorated(true);
+ setSize(700, 700);
+
+ Point pt =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
+
+ this.setLocation(pt.x - (350), pt.y - (350));
+
+ enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ initUI();
+
+ addActions();
+
+ updateKeyTableData();
+ }
+
+ private void initUI()
+ {
+ this.getContentPane().setLayout(new BorderLayout(5, 5));
+
+ // Top Panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+
+ addAESKeyButton = new JButton("Add AES Key");
+ addAESKeyButton.setSize(new Dimension(30, 100));
+ addGenericKeyButton = new JButton("Add Text Key");
+ addGenericKeyButton.setSize(new Dimension(30, 100));
+ removeKeyButton = new JButton("Remove Key(s)");
+ removeKeyButton.setSize(new Dimension(30, 100));
+
+ topPanel.add(addAESKeyButton);
+ topPanel.add(addGenericKeyButton);
+ topPanel.add(removeKeyButton);
+
+ this.getContentPane().add(topPanel, BorderLayout.NORTH);
+
+
+ // Middle and list panel
+ JPanel midPanel = new JPanel();
+ midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ midPanel.setLayout(new BorderLayout(5, 5));
+
+ JLabel keyListLabel = new JLabel("Secret Keys:");
+
+ Object[][] data = {};
+ String[] columnNames = {"Key Alias", "Key Type", "Key Value"};
+
+ keyDataModel = new DefaultTableModel(data, columnNames);
+ keyDataTable = new JTable(keyDataModel);
+ JScrollPane scrollPane = new JScrollPane(keyDataTable);
+ keyDataTable.setFillsViewportHeight(true);
+
+ midPanel.add(keyListLabel, BorderLayout.NORTH);
+ midPanel.add(scrollPane, BorderLayout.CENTER);
+
+ this.getContentPane().add(midPanel, BorderLayout.CENTER);
+
+ // Bottom Panel
+ JPanel bottomPanel = new JPanel();
+ bottomPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+
+ quitButton = new JButton("Quit");
+ quitButton.setSize(new Dimension(30, 100));
+ bottomPanel.add(quitButton);
+
+ this.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
+ }
+
+ private void addActions()
+ {
+ addAESKeyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ addAESKey();
+ }
+ });
+
+ addGenericKeyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ addTextKey();
+ }
+ });
+
+ removeKeyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ removeKeys();
+ }
+ });
+
+ quitButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ System.exit(-1);
+ }
+ });
+ }
+
+ private void addAESKey()
+ {
+ final String input = JOptionPane.showInputDialog(this, "Key Alias
Name:", "Generate New random AES Secret Key", JOptionPane.OK_CANCEL_OPTION);
+ if (input != null && !input.trim().isEmpty())
+ {
+ // generate a new random secret key
+ try
+ {
+ final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ final SecureRandom random = new SecureRandom(); // cryptograph. secure
random
+ keyGen.init(random);
+ final SecretKey key = keyGen.generateKey();
+
+ mgr.clearKey(input);
+ mgr.setKey(input, key);
+
+ updateKeyTableData();
+ }
+ catch (Exception e)
+ {
+ JOptionPane.showMessageDialog(this, "Failed to add random new AES
key: " + e.getMessage(), "Add Key Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ private void addTextKey()
+ {
+
+ final JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+
+ final JPanel topPanel = new JPanel();
+ final JLabel aliasLabel = new JLabel("Alias:");
+ aliasLabel.setSize(60, 30);
+ final JTextField aliasField = new JTextField(40);
+
+ topPanel.add(aliasLabel);
+ topPanel.add(aliasField);
+
+ final JPanel bottomPanel = new JPanel();
+ final JLabel keyLabel = new JLabel("Key:");
+ keyLabel.setSize(60, 30);
+ final JTextField keyField = new JTextField(40);
+
+ bottomPanel.add(keyLabel);
+ bottomPanel.add(keyField);
+
+
+ panel.add(topPanel, BorderLayout.NORTH);
+ panel.add(bottomPanel, BorderLayout.SOUTH);
+
+ final String[] options = new String[]{"OK", "Cancel"};
+ int option = JOptionPane.showOptionDialog(null, panel, "Generate New
Text Based Secret Key ",
+ JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
+ null, options, options[0]);
+
+ if (option == JOptionPane.OK_OPTION)
+ {
+ final String alias = aliasField.getText();
+ final String keyText = keyField.getText();
+
+
+ if ((alias != null && !alias.trim().isEmpty()) &&
+ keyText != null && !keyText.trim().isEmpty())
+ {
+ // generate a new random secret key
+ try
+ {
+ byte[] key = keyText.getBytes("UTF-8");
+ MessageDigest sha = MessageDigest.getInstance("SHA-1");
+ key = sha.digest(key);
+ key = Arrays.copyOf(key, 16); // use only first 128 bit
+
+ mgr.clearKey(alias);
+ mgr.setKey(alias, new SecretKeySpec(key, "AES"));
+
+ updateKeyTableData();
+ }
+ catch (Exception e)
+ {
+ JOptionPane.showMessageDialog(this, "Failed to add new text based
secret key: " + e.getMessage(), "Add Key Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+ }
+
+ private void removeKeys()
+ {
+ if (keyDataTable.getSelectedRowCount() == 0)
+ {
+ JOptionPane.showMessageDialog(this, "No keys are selected.", "Remove
Keys", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+ else if (JOptionPane.showConfirmDialog(this, "Are you sure you want to
removed the selected Keys?", "Remove Keys", JOptionPane.YES_NO_OPTION) ==
JOptionPane.YES_OPTION)
+ {
+ int[] rows = keyDataTable.getSelectedRows();
+ for (int row : rows)
+ {
+ final String alias = (String)keyDataTable.getValueAt(row, 0);
+
+ try
+ {
+ mgr.clearKey(alias);
+ }
+ catch (Exception e)
+ {
+ JOptionPane.showMessageDialog(this, "Failed to remove key with
alias " + alias + ":" + e.getMessage(),
+ "Remove Key Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ updateKeyTableData();
+ }
+
+
+ }
+
+ private void updateKeyTableData()
+ {
+ try
+ {
+ for (int ctx = (keyDataModel.getRowCount() -1 ); ctx >=0; --ctx)
+ {
+ keyDataModel.removeRow(ctx);
+
+ }
+ // get all of the data from the token
+ Map<String, Key> keys = mgr.getAllKeys();
+ for (Entry<String, Key> entry : keys.entrySet())
+ {
+ String type = "";
+ final Object value = entry.getValue();
+ if (value instanceof SecretKey)
+ type = "Secret Key: " + ((Key)value).getAlgorithm();
+ else if (value instanceof PublicKey)
+ type = "Public Key: " + ((Key)value).getAlgorithm();
+ else if (value instanceof PrivateKey)
+ type = "Private Key: " + ((Key)value).getAlgorithm();
+ else
+ type = value.getClass().toString();
+
+ keyDataModel.addRow(new Object[] {entry.getKey(), type ,"***"});
+ keyDataModel.fireTableDataChanged();
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
+///CLOVER:ON
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/TokenLoginCallback.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,52 @@
+package org.nhindirect.common.crypto.tools;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+
+///CLOVER:OFF
+public class TokenLoginCallback implements CallbackHandler
+{
+ public Object waitObject = new Object();
+
+ public boolean loginSuccessful = false;
+
+ public TokenLoginCallback()
+ {
+ }
+
+ @Override
+ public synchronized void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException
+ {
+ for (Callback callback : callbacks)
+ {
+ if (callback instanceof PasswordCallback)
+ {
+ final JPanel panel = new JPanel();
+ final JLabel label = new JLabel("Enter hardware token password:");
+ final JPasswordField pass = new JPasswordField(20);
+ panel.add(label);
+ panel.add(pass);
+ final String[] options = new String[]{"OK", "Cancel"};
+ int option = JOptionPane.showOptionDialog(null, panel, "Token ",
+ JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
+ null, options, options[0]);
+
+ if(option == JOptionPane.OK_OPTION) // pressing OK button
+ {
+ ((PasswordCallback)callback).setPassword(pass.getPassword());
+ }
+ }
+ }
+
+ this.notifyAll();
+ }
+}
+///CLOVER:ON
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/commands/KeyModel.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,34 @@
+package org.nhindirect.common.crypto.tools.commands;
+
+import java.security.Key;
+
+public class KeyModel
+{
+ protected final String keyName;
+ protected final Key key;
+ protected final char[] keyText;
+
+ public KeyModel(String keyName, Key key, char[] keyText)
+ {
+ this.keyName = keyName;
+ this.key = key;
+ this.keyText = keyText;
+ }
+
+ public String getKeyName()
+ {
+ return keyName;
+ }
+
+ public Key getKey()
+ {
+ return key;
+ }
+
+ public char[] getKeyText()
+ {
+ return keyText;
+ }
+
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/commands/PKCS11Commands.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,145 @@
+package org.nhindirect.common.crypto.tools.commands;
+
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.tools.commands.printers.KeyPrinter;
+import org.nhindirect.common.tooling.Command;
+import org.nhindirect.common.tooling.StringArrayUtil;
+
+public class PKCS11Commands
+{
+ private static final String LIST_SECRET_KEYS = "Lists secret keys in
the HSM";
+
+ private static final String ADD_RANDOM_SECRET_KEY = "Creates a new
named random AES128 secret key\r\n" +
+ "\r\n keyName" +
+ "\r\n\t keyName: The unique name of the new secret key. Place
the key name in quotes (\"\") if there are spaces in the name.";
+
+ private static final String ADD_USER_SECRET_KEY = "Creates a new named
AES128 secret key via user entered text\r\n" +
+ "\r\n keyName keyText" +
+ "\r\n\t keyName: The unique name of the new secret key. Place
the key name in quotes (\"\") if there are spaces in the name." +
+ "\r\n\t keyText: The user entered key text. Place the text in
quotes (\"\") if there are spaces in the text.";
+
+ private static final String REMOVE_SECRET_KEY = "Removes a new named
secret key\r\n " +
+ "\r\n keyName" +
+ "\r\n\t keyName: The unique name of the secret key. Place the
key name in quotes (\"\") if there are spaces in the name.";
+
+ protected final KeyPrinter keyPrinter;
+
+ protected final MutableKeyStoreProtectionManager mgr;
+
+ public PKCS11Commands(MutableKeyStoreProtectionManager mgr)
+ {
+ this.mgr = mgr;
+ this.keyPrinter = new KeyPrinter();
+ }
+
+ @Command(name = "ListSecretKeys", usage = LIST_SECRET_KEYS)
+ public void listCerts(String[] args)
+ {
+ try
+ {
+ // get all of the data from the token
+ final Map<String, Key> keys = mgr.getAllKeys();
+
+ if (keys.isEmpty())
+ System.out.println("No keys found");
+
+ else
+ {
+ final Collection<KeyModel> models = new ArrayList<KeyModel>();
+
+ for (Entry<String, Key> entry : keys.entrySet())
+ {
+ char[] keyText = (entry.getValue().getEncoded() !=
null) ? "*****".toCharArray() : "Not Extractable".toCharArray();
+
+ final KeyModel keyModel = new KeyModel(entry.getKey(),
entry.getValue(), keyText);
+ models.add(keyModel);
+ }
+
+ keyPrinter.printRecords(models);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ @Command(name = "CreateRandomSecretKey", usage = ADD_RANDOM_SECRET_KEY)
+ public void addRandomSecretKey(String[] args)
+ {
+ final String keyName = StringArrayUtil.getRequiredValue(args, 0);
+
+ // generate a new random secret key
+ try
+ {
+ final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ final SecureRandom random = new SecureRandom(); // cryptograph. secure
random
+ keyGen.init(random);
+ final SecretKey key = keyGen.generateKey();
+
+ mgr.clearKey(keyName);
+ mgr.setKey(keyName, key);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Failed to add new random secret key: " +
e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ @Command(name = "CreateUserSecretKey", usage = ADD_USER_SECRET_KEY)
+ public void addUserSecretKey(String[] args)
+ {
+ final String keyName = StringArrayUtil.getRequiredValue(args, 0);
+ final String keyText = StringArrayUtil.getRequiredValue(args, 1);
+
+ try
+ {
+ byte[] key = keyText.getBytes("UTF-8");
+ MessageDigest sha = MessageDigest.getInstance("SHA-1");
+ key = sha.digest(key);
+ key = Arrays.copyOf(key, 16); // use only first 128 bit
+
+ mgr.clearKey(keyName);
+ mgr.setKey(keyName, new SecretKeySpec(key, "AES"));
+ }
+ catch (Exception e)
+ {
+ System.err.println("Failed to add new random secret key: " +
e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ @Command(name = "RemoveSecretKey", usage = REMOVE_SECRET_KEY)
+ public void removeSecretKey(String[] args)
+ {
+ String keyName = StringArrayUtil.getRequiredValue(args, 0);
+
+ // remove secret key
+ try
+ {
+
+ mgr.clearKey(keyName);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Failed to add new random secret key: " +
e.getMessage());
+ }
+ }
+
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/crypto/tools/commands/printers/KeyPrinter.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,65 @@
+package org.nhindirect.common.crypto.tools.commands.printers;
+
+import java.security.Key;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.nhindirect.common.crypto.tools.commands.KeyModel;
+import org.nhindirect.common.tooling.printer.AbstractRecordPrinter;
+
+public class KeyPrinter extends AbstractRecordPrinter<KeyModel>
+{
+ protected static final Collection<ReportColumn> REPORT_COLS;
+
+ protected static final String KEY_NAME_COL = "Key Name";
+ protected static final String KEY_TYPE_COL = "Key Type";
+ protected static final String KEY_TEXT_COL = "Key Text";
+
+ static
+ {
+ REPORT_COLS = new ArrayList<ReportColumn>();
+
+ REPORT_COLS.add(new ReportColumn(KEY_NAME_COL, 40, "KeyName"));
+ REPORT_COLS.add(new ReportColumn(KEY_TYPE_COL, 25, "KeyType"));
+ REPORT_COLS.add(new ReportColumn(KEY_TEXT_COL, 16, "KeyText"));
+ }
+
+ public KeyPrinter()
+ {
+ super(81, REPORT_COLS);
+ }
+
+ @Override
+ protected String getColumnValue(ReportColumn column, KeyModel model)
+ {
+
+ try
+ {
+ if (column.getHeader().equals(KEY_TYPE_COL))
+ {
+ String type = "";
+ final Key key = model.getKey();
+ if (key instanceof javax.crypto.SecretKey)
+ type = "Secret Key: " + key.getAlgorithm();
+ else if (key instanceof java.security.PublicKey)
+ type = "Public Key: " + key.getAlgorithm();
+ else if (key instanceof java.security.PrivateKey)
+ type = "Private Key: " + key.getAlgorithm();
+ else
+ type = key.getClass().toString();
+
+ return type;
+ }
+ else if (column.getHeader().equals(KEY_TEXT_COL))
+ {
+ return new String(model.getKeyText());
+ }
+ else
+ return super.getColumnValue(column, model);
+ }
+ catch (Exception e)
+ {
+ return "ERROR: " + e.getMessage();
+ }
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/MDNStandard.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,339 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Umesh Madan ume...@microsoft.com
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.mail;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Provides constants and utility functions for working with MDN
+ * @author Greg Meyer
+ * @author Umesh Madan
+ * @since 1.1
+ */
+public class MDNStandard
+{
+ private static final Log LOGGER =
LogFactory.getFactory().getInstance(MDNStandard.class);
+
+ private static Class<?> dsnClass;
+ private static Method getHeaders;
+
+ static
+ {
+ try
+ {
+ dsnClass =
MDNStandard.class.getClassLoader().loadClass("com.sun.mail.dsn.DispositionNotification");
+ getHeaders = dsnClass.getMethod("getNotifications");
+ }
+ catch (Exception e) {/* no-op */}
+ }
+
+ /**
+ * MIME types for MDN
+ * @author Greg Meyer
+ * @author Umesh Madan
+ *
+ */
+ public static class MediaType
+ {
+ /**
+ * Base MIME type for an MDN
+ */
+ public static final String ReportMessage = "multipart/report";
+
+ /**
+ * MIME type with qualifier for a disposition report.
+ */
+ public static final String DispositionReport = ReportMessage + ";
report-type=disposition-notification";
+
+ /**
+ * MIME type for the disposition notification body part of the
multipart/report report
+ */
+ public static final String DispositionNotification
= "message/disposition-notification";
+
+ /**
+ * MIME parameter header for an report.
+ */
+ public static final String ReportType = "report-type";
+
+ /**
+ * Report parameter value indication an MDN message.
+ */
+ public static final String ReportTypeValueNotification
= "disposition-notification";
+ }
+
+ /**
+ * Standard header names for MDN headers
+ * @author Greg Meyer
+ * @author Umesh Madan
+ *
+ */
+ public static class Headers
+ {
+
+ /**
+ * Disposition header field name.
+ * <p>
+ * RFC 3798, Disposition field, 3.2.6
+ */
+ public static final String Disposition = "Disposition";
+
+ /**
+ * Disposition-Notification-To header name
+ * <p>
+ * RFC 3798, The Disposition-Notification-To Header, 2.1
+ */
+ public static final String DispositionNotificationTo
= "Disposition-Notification-To";
+
+ /**
+ * Disposition-Notification-Options header name
+ * <p>
+ * RFC 3798, The Disposition-Notification-Options Header, 2.2
+ */
+ public static final String DispositionNotificationOptions
= "Disposition-Notification-Options";
+
+ /**
+ * Reporting-UA field name (value is the Health Internet Addresa and
software that triggered notification)
+ * <p>
+ * RFC 3798, The Reporting-UA field, 3.2.1
+ */
+ public static final String ReportingAgent = "Reporting-UA";
+
+ /**
+ * MDN-Gateway field name (for SMTP to non-SMTP gateways -- e.g., XDD
to SMTP)
+ * <p>
+ * RFC 3798, The MDN-Gateway field, 3.2.2
+ */
+ public static final String Gateway = "MDN-Gateway";
+
+ /**
+ * Original-Message-ID field name (value is message for which
notification is being sent)
+ * <p>
+ * RFC 3798, Original-Message-ID field, 3.2.5
+ */
+ public static final String OriginalMessageID = "Original-Message-ID";
+
+ /**
+ * Final recipient field name.
+ */
+ public static final String FinalRecipient = "Final-Recipient";
+
+ /**
+ * Failure field name, value is original failure text (e.g.,
exception)
+ * <p>
+ * RFC 3798, Failure, Error and Warning fields, 3.2.7
+ */
+ public static final String Failure = "Failure";
+
+ /**
+ * Error field name, value is original error text (e.g., HL7 error
report)
+ * <p>
+ * RFC 3798, Failure, Error and Warning fields, 3.2.7
+ */
+ public static final String Error = "Error";
+
+ /**
+ * Warning field name, value is original warning text
+ * <p>
+ * RFC 3798, Failure, Error and Warning fields, 3.2.7
+ */
+ public static final String Warning = "Warning";
+ }
+
+ public static final String Action_Manual = "manual-action";
+ public static final String Action_Automatic = "automatic-action";
+ public static final String Send_Manual = "MDN-sent-manually";
+ public static final String Send_Automatic = "MDN-sent-automatically";
+ public static final String Disposition_Displayed = "displayed";
+ public static final String Disposition_Processed = "processed";
+ public static final String Disposition_Dispatched = "dispatched";
+ public static final String Disposition_Deleted = "deleted";
+ public static final String Disposition_Denied = "denied";
+ public static final String Disposition_Error = "error";
+ public static final String Modifier_Error = "error";
+
+ public static final String ReportType = "report-type";
+ public static final String ReportTypeValueNotification
= "disposition-notification";
+
+ /**
+ * Direct specific dispostion options for requesting timely and
reliable messaging.
+ * Also used as the MDN report extension field for indicating an MDN
in response to a timely and reliable request.
+ */
+ public static final String DispositionOption_TimelyAndReliable
= "X-DIRECT-FINAL-DESTINATION-DELIVERY";
+
+ /**
+ * Gets an MDN field such as the message dispostion from a MimeMessage.
+ * @param msg The message to retrieve the field from.
+ * @param field The field to extract from the message.
+ * @return The value of the field. If the message is not an MDN message
(<a href="http://tools.ietf.org/html/rfc3798">RFC 3798</a>) or the
+ * field does not exist, an empty string is returned.
+ */
+ public static String getMDNField(MimeMessage msg, String field)
+ {
+ InternetHeaders headers = null;
+
+ try
+ {
+ // use the help function from the Direct specification... will throw and
+ // exception if the message is not an MDN message or cannot parse the
fields
+ headers = MDNStandard.getNotificationFieldsAsHeaders(msg);
+ }
+ catch (IllegalArgumentException e)
+ {
+ LOGGER.warn("Failed to retrieve MDN field from message. Message may
not be an MDN message.", e);
+ }
+
+ if (headers != null)
+ {
+ // disposition fields are returned from the helper function as a
standard list of internet headers
+ final String fieldValue = headers.getHeader(field, ",");
+ if (fieldValue != null)
+ return fieldValue;
+ }
+
+ return "";
+ }
+
+ /**
+ * Parses the notification part fields of a MDN MimeMessage message. The
message is expected to conform to the MDN specification
+ * as described in RFC3798.
+ * @return The notification part fields as a set of Internet headers.
+ */
+ public static InternetHeaders getNotificationFieldsAsHeaders(MimeMessage
message)
+ {
+ if (message == null)
+ throw new IllegalArgumentException("Message can not be null");
+
+ MimeMultipart mm = null;
+
+ try
+ {
+ ByteArrayDataSource dataSource = new
ByteArrayDataSource(message.getRawInputStream(), message.getContentType());
+ mm = new MimeMultipart(dataSource);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Failed to parse notification
fields.", e);
+ }
+
+ return getNotificationFieldsAsHeaders(mm);
+ }
+
+
+ /**
+ * Parses the notification part fields of the MimeMultipart body of a MDN
message. The multipart is expected to conform to the MDN specification
+ * as described in RFC3798.
+ * @return The notification part fields as a set of Internet headers.
+ */
+ public static InternetHeaders
getNotificationFieldsAsHeaders(MimeMultipart mm)
+ {
+ InternetHeaders retVal = null;
+
+ if (mm == null)
+ throw new IllegalArgumentException("Multipart can not be null");
+
+ try
+ {
+ if (mm.getCount() < 2)
+ throw new IllegalArgumentException("Multipart can not be null");
+
+ // the second part should be the notification
+ BodyPart part = mm.getBodyPart(1);
+
+ try
+ {
+ Object contecntObj = part.getContent();
+ if (dsnClass != null &&
dsnClass.getCanonicalName().equals(contecntObj.getClass().getCanonicalName()))
+ {
+ retVal = (InternetHeaders)getHeaders.invoke(contecntObj);
+ return retVal;
+ }
+ }
+ catch(Exception e) {/* no-op */}
+
+ if
(!part.getContentType().equalsIgnoreCase(MDNStandard.MediaType.DispositionNotification))
+ throw new IllegalArgumentException("Notification part content type is
not " + MDNStandard.MediaType.DispositionNotification);
+
+ // parse fields
+ retVal = new InternetHeaders();
+ String[] fields = getPartContentBodyAsString(part).split("\r\n");
+ for (String field : fields)
+ {
+ int idx = field.indexOf(":");
+ if (idx > -1)
+ {
+ String name = field.substring(0, idx);
+ String value = field.substring(idx + 1).trim();
+ retVal.setHeader(name, value);
+ }
+ }
+
+ }
+ catch (MessagingException e)
+ {
+ throw new IllegalArgumentException("Failed to parse notification
fields.", e);
+ }
+
+ return retVal;
+
+ }
+
+ /*
+ * Gets the content of a body part as a string. The content may
internally be stored using several constructs such as a stream.
+ */
+ ///CLOVER:OFF
+ protected static String getPartContentBodyAsString(BodyPart part)
+ {
+ try
+ {
+ Object content = part.getContent();
+
+ if (content instanceof String)
+ return content.toString();
+ else if (content instanceof InputStream)
+ {
+ InputStream str = (InputStream)part.getContent();
+ byte[] bytes = new byte[str.available()];
+ str.read(bytes);
+ return new String(bytes);
+ }
+ else
+ return content.toString();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Unable to handle get notification
body as a string.", e);
+ }
+ }
+ ///CLOVER:ON
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/MailStandard.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,82 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.mail;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Common RFC822/5322 headers and common header collections.
+ * @author Greg Meyer
+ * @author Umesh Madan
+ *
+ */
+public class MailStandard
+{
+ private static final Log LOGGER =
LogFactory.getFactory().getInstance(MailStandard.class);
+
+ public static class Headers
+ {
+ public static final String To = "to";
+ public static final String CC = "cc";
+ public static final String BCC = "bcc";
+ public static final String From = "from";
+ public static final String Sender = "sender";
+ public static final String MessageID = "message-id";
+ public static final String Subject = "subject";
+ public static final String Date = "date";
+ public static final String OrigDate = "orig-date";
+ public static final String InReplyTo = "in-reply-to";
+ public static final String References = "references";
+ public static final String ContentType = "content-type";
+ }
+
+
+ /**
+ * Gets a specific header from the message
+ * @param msg The message to extract the message from.
+ * @param headerName The header name.
+ * @return The value of the header. Return an empty string if the header
is not found.
+ */
+ public static String getHeader(MimeMessage msg, String headerName)
+ {
+ String retVal = "";
+
+ try
+ {
+ retVal = msg.getHeader(headerName, ",");
+ if (retVal == null)
+ retVal = "";
+ }
+ catch (MessagingException e)
+ {
+ ///CLOVER:OFF
+ LOGGER.warn("Failed to retrieve header \"" + headerName + "\" from
message.", e);
+ ///CLOVER:ON
+ }
+
+ return retVal;
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/MailUtil.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,61 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.mail;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.mail.internet.MimePart;
+
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Generic mail utility methods
+ * @author Greg Meyer
+ * @since 1.1
+ */
+public class MailUtil
+{
+ /**
+ * Serializes a MimePart to a byte array
+ * @param message The message to serializes
+ * @return The message as a byte array.
+ */
+ public static byte[] serializeToBytes(MimePart message)
+ {
+ byte[] retVal;
+ try
+ {
+ ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+ message.writeTo(oStream);
+ oStream.flush();
+ retVal = oStream.toByteArray();
+ IOUtils.closeQuietly(oStream);
+
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Failed to serialize message to
bytes.", e);
+ }
+
+ return retVal;
+ }
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/SMIMEStandard.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,59 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Umesh Madan ume...@microsoft.com
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.mail;
+
+/**
+ * Standard SMIM headers and utility methods
+ * @author Greg Meyer
+ * @author Umesh Madan
+ * @since 1.1
+ */
+public class SMIMEStandard
+{
+ //
+ // MIME Types
+ //
+ public static final String MediaType_Multipart = "multipart";
+ public static final String MultiPartType_Mixed = "multipart/mixed;";
+ public static final String MultiPartType_Signed = "multipart/signed;
protocol=\"application/x-pkcs7-signature\";";
+ public static final String MICAlgorithmKey = "micalg"; // Message
Integrity Check Protocol
+
+ //
+ // Cryptography
+ //
+ public static final String CmsEnvelopeMediaType
= "application/pkcs7-mime";
+ public static final String CmsEnvelopeMediaTypeAlt
= "application/x-pkcs7-mime"; // we are forgiving when we receive messages
+
+ public static final String EncryptedContentTypeHeaderValue
= "application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
+ public static final String EncryptedContentMediaType
= "application/pkcs7-mime";
+ public static final String EncryptedContentMediaTypeAlternative
= "application/x-pkcs7-mime"; // we are forgiving when we receive messages
+ public static final String SignatureContentTypeHeaderValue
= "application/pkcs7-signature; name=\"smime.p7s\"";
+ public static final String SignatureContentMediaType
= "application/pkcs7-signature";
+ public static final String SignatureContentMediaTypeAlternative
= "application/x-pkcs7-signature"; // we are forgiving when we receive
messages
+ public static final String SignatureDisposition = "attachment;
filename=\"smime.p7s\"";
+
+ public static final String SmimeTypeParameterKey = "smime-type";
+ public static final String EnvelopedDataSmimeType = "enveloped-data";
+ public static final String SignedDataSmimeType = "signed-data";
+ public static final String DefaultFileName = "smime.p7m";
+}
=======================================
--- /dev/null
+++
/java/tags/direct-common-1.4.2/src/main/java/org/nhindirect/common/mail/dsn/DSNFailureTextBodyPartGenerator.java
Thu Dec 18 00:42:12 2014 UTC
@@ -0,0 +1,49 @@
+/*
+Copyright (c) 2010, NHIN Direct Project
+All rights reserved.
+
+Authors:
+ Greg Meyer gm2...@cerner.com
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
+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. Neither the name of the The NHIN Direct Project
(nhindirect.org).
+nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+*/
+
+package org.nhindirect.common.mail.dsn;
+
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.mail.Address;
+import javax.mail.Header;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeBodyPart;
+
+/**
+ * Generator interface for creating the human readable part of a DSN
message.
+ * @author gm2552
+ * @since 1.1
+ */
+public interface DSNFailureTextBodyPartGenerator
+{
+ /**
+ * Generates the human readable section of a DSN message with
pre-populated information.
+ * @param originalSender The original sender of the message.
+ * @param failedRecipients List of recipients that did not receive the
original message.
+ * @param originalMessageHeaders Enumeration of the headers of the
original message.
+ * @return A mime body part containing the content of the human readable
section of the DSN message
+ * @throws MessagingException
+ */
+ public MimeBodyPart generate(Address originalSender, List<Address>
failedRecipients,
+ Enumeration<Header> originalMessageHeaders) throws
MessagingException;
+}
=======================================
***Additional files exist in this changeset.***
Reply all
Reply to author
Forward
0 new messages