[direct-certificate-discovery-tool] 6 new revisions pushed by michal.kotelba@esacinc.com on 2014-05-05 13:41 GMT

2 views
Skip to first unread message

direct-certifica...@googlecode.com

unread,
May 5, 2014, 9:41:56 AM5/5/14
to dcdt...@googlegroups.com
6 new revisions:

Revision: 71ed9e18974e
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Sun May 4 20:51:50 2014 UTC
Log: - Supports DCDT-220....
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=71ed9e18974e

Revision: d11399541551
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 00:25:45 2014 UTC
Log: - Supports DCDT-40....
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=d11399541551

Revision: 58717c73d749
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 00:41:11 2014 UTC
Log: - Further supports DCDT-40....
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=58717c73d749

Revision: 16e9aa2fb07d
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 03:47:29 2014 UTC
Log: - Supports DCDT-221....
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=16e9aa2fb07d

Revision: 5fe9e009e7c8
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 05:22:45 2014 UTC
Log: - Further supports DCDT-221....
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=5fe9e009e7c8

Revision: 9aa91aa9e4a3
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 07:15:57 2014 UTC
Log: - Further supports DCDT-220....
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=9aa91aa9e4a3

==============================================================================
Revision: 71ed9e18974e
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Sun May 4 20:51:50 2014 UTC
Log: - Supports DCDT-220.
- Disabled full signer verification until a workaround can be implemented.
- Implemented downloading of Discovery credentials via the admin console.
- Fixed key writing to output the encoded key spec instead of the actual
key object itself.
- Increased mail server system resource limits.
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=71ed9e18974e

Added:
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/compress/ArchiveType.java
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/compress/utils/ArchiveUtils.java

/dcdt-core/src/test/java/gov/hhs/onc/dcdt/compress/utils/ArchiveUtilsUnitTests.java
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/HttpHeaderNames.java
Modified:
/dcdt-core/pom.xml
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/PemType.java
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/keys/KeyAlgorithm.java

/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CertificateUtils.java

/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CryptographyUtils.java
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/KeyUtils.java
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/PemUtils.java

/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtils.java
/dcdt-core/src/test/java/gov/hhs/onc/dcdt/crypto/keys/KeyInfoUnitTests.java

/dcdt-core/src/test/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtilsFunctionalTests.java
/dcdt-core/src/test/resources/META-INF/core/core-test.properties
/dcdt-parent/pom.xml
/dcdt-service-core/pom.xml
/dcdt-service-dns/pom.xml
/dcdt-service-ldap/pom.xml
/dcdt-service-mail/pom.xml

/dcdt-service-mail/src/main/resources/META-INF/spring/spring-service-mail.xml
/dcdt-web/pom.xml

/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/AbstractToolController.java

/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/AdminController.java

/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/DiscoveryController.java
/dcdt-web/src/main/webapp/WEB-INF/views/content/content-admin.jsp
/dcdt-web/src/main/webapp/WEB-INF/views/content/head-admin.jsp
/dcdt-web/src/main/webapp/WEB-INF/views/include/head.jsp
/dcdt-web/src/main/webapp/static/scripts/admin.js
/dcdt-web/src/main/webapp/static/styles/admin.css

=======================================
--- /dev/null
+++ /dcdt-core/src/main/java/gov/hhs/onc/dcdt/compress/ArchiveType.java Sun
May 4 20:51:50 2014 UTC
@@ -0,0 +1,39 @@
+package gov.hhs.onc.dcdt.compress;
+
+import gov.hhs.onc.dcdt.net.mime.CoreContentTypes;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.springframework.util.MimeType;
+
+public enum ArchiveType {
+ ZIP(ArchiveStreamFactory.ZIP, ".zip", new
MimeType(CoreContentTypes.APP_TYPE, "zip"), ZipArchiveEntry.class);
+
+ private final String type;
+ private final String fileExt;
+ private final MimeType contentType;
+ private final Class<? extends ArchiveEntry> entryClass;
+
+ private ArchiveType(String type, String fileExt, MimeType contentType,
Class<? extends ArchiveEntry> entryClass) {
+ this.type = type;
+ this.fileExt = fileExt;
+ this.contentType = contentType;
+ this.entryClass = entryClass;
+ }
+
+ public MimeType getContentType() {
+ return this.contentType;
+ }
+
+ public Class<? extends ArchiveEntry> getEntryClass() {
+ return this.entryClass;
+ }
+
+ public String getFileExtension() {
+ return this.fileExt;
+ }
+
+ public String getType() {
+ return this.type;
+ }
+}
=======================================
--- /dev/null
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/compress/utils/ArchiveUtils.java
Sun May 4 20:51:50 2014 UTC
@@ -0,0 +1,120 @@
+package gov.hhs.onc.dcdt.compress.utils;
+
+import gov.hhs.onc.dcdt.collections.impl.AbstractToolTransformer;
+import gov.hhs.onc.dcdt.compress.ArchiveType;
+import gov.hhs.onc.dcdt.utils.ToolArrayUtils;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map.Entry;
+import javax.annotation.Nullable;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.ArchiveStreamFactory;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+public abstract class ArchiveUtils {
+ public static class ZipArchiveEntryPairTransformer extends
AbstractArchiveEntryPairTransformer<ZipArchiveEntry> {
+ public final static ZipArchiveEntryPairTransformer INSTANCE = new
ZipArchiveEntryPairTransformer();
+
+ @Override
+ protected ZipArchiveEntry createEntry(Entry<String, byte[]>
entryDescPair) {
+ ZipArchiveEntry entry = new
ZipArchiveEntry(entryDescPair.getKey());
+ entry.setSize(entryDescPair.getValue().length);
+
+ return entry;
+ }
+ }
+
+ public abstract static class AbstractArchiveEntryPairTransformer<T
extends ArchiveEntry> extends
+ AbstractToolTransformer<Entry<String, byte[]>, Pair<T, byte[]>> {
+ @Override
+ protected Pair<T, byte[]> transformInternal(Entry<String, byte[]>
entryDescPair) throws Exception {
+ return new MutablePair<>(this.createEntry(entryDescPair),
entryDescPair.getValue());
+ }
+
+ protected abstract T createEntry(Entry<String, byte[]>
entryDescPair);
+ }
+
+ // @formatter:off
+ /*
+ @SuppressWarnings({ "unchecked" })
+ public static <T extends ArchiveEntry> List<Pair<T, byte[]>>
readArchive(ArchiveType type, InputStream inStream) throws ArchiveException
{
+ try (ArchiveInputStream archiveInStream = new
ArchiveStreamFactory().createArchiveInputStream(type.getType(), inStream)) {
+ List<Pair<T, byte[]>> entryPairs = new ArrayList<>();
+ T entry;
+ long entrySize;
+
+ while ((entry = ((T) archiveInStream.getNextEntry())) != null)
{
+ if ((entrySize = entry.getSize()) ==
ArchiveEntry.SIZE_UNKNOWN) {
+ continue;
+ }
+
+ try {
+ entryPairs.add(new MutablePair<>(entry,
IOUtils.toByteArray(archiveInStream, entrySize)));
+ } catch (IOException e) {
+ throw new ArchiveException(String.format("Unable to
read archive (type=%s) entry (name=%s, size=%d).", type.name(),
entry.getName(),
+ entry.getSize()), e);
+ }
+ }
+
+ return entryPairs;
+ } catch (IOException e) {
+ throw new ArchiveException(String.format("Unable to close
archive (type=%s) input stream.", type.name()), e);
+ }
+ }
+ */
+ // @formatter:on
+
+ @SafeVarargs
+ @SuppressWarnings({ "varargs" })
+ public static <T extends ArchiveEntry> byte[] writeArchive(ArchiveType
type, @Nullable Entry<T, byte[]> ... entryPairs) throws ArchiveException {
+ return writeArchive(type, ToolArrayUtils.asList(entryPairs));
+ }
+
+ public static <T extends ArchiveEntry> byte[] writeArchive(ArchiveType
type, @Nullable Iterable<? extends Entry<T, byte[]>> entryPairs)
+ throws ArchiveException {
+ try (ByteArrayOutputStream outStream = new
ByteArrayOutputStream()) {
+ writeArchive(type, outStream, entryPairs);
+ outStream.flush();
+
+ return outStream.toByteArray();
+ } catch (IOException e) {
+ throw new ArchiveException(String.format("Unable to write
archive (type=%s) data.", type.name()), e);
+ }
+ }
+
+ @SafeVarargs
+ @SuppressWarnings({ "varargs" })
+ public static <T extends ArchiveEntry> void writeArchive(ArchiveType
type, OutputStream outStream, @Nullable Entry<T, byte[]> ... entryPairs)
+ throws ArchiveException {
+ writeArchive(type, outStream, ToolArrayUtils.asList(entryPairs));
+ }
+
+ public static <T extends ArchiveEntry> void
+ writeArchive(ArchiveType type, OutputStream outStream, @Nullable
Iterable<? extends Entry<T, byte[]>> entryPairs) throws ArchiveException {
+ try (ArchiveOutputStream archiveOutStream = new
ArchiveStreamFactory().createArchiveOutputStream(type.getType(),
outStream)) {
+ if (entryPairs == null) {
+ return;
+ }
+
+ for (Entry<T, byte[]> entryPair : entryPairs) {
+ try {
+ archiveOutStream.putArchiveEntry(entryPair.getKey());
+ archiveOutStream.write(entryPair.getValue());
+ archiveOutStream.closeArchiveEntry();
+ } catch (IOException e) {
+ throw new ArchiveException(String.format("Unable to
write archive (type=%s) entry (name=%s, size=%d).", type.name(),
entryPair.getKey()
+ .getName(), entryPair.getValue().length), e);
+ }
+ }
+
+ archiveOutStream.finish();
+ } catch (IOException e) {
+ throw new ArchiveException(String.format("Unable to close
archive (type=%s) output stream.", type.name()), e);
+ }
+ }
+}
=======================================
--- /dev/null
+++
/dcdt-core/src/test/java/gov/hhs/onc/dcdt/compress/utils/ArchiveUtilsUnitTests.java
Sun May 4 20:51:50 2014 UTC
@@ -0,0 +1,68 @@
+package gov.hhs.onc.dcdt.compress.utils;
+
+import gov.hhs.onc.dcdt.compress.ArchiveType;
+import
gov.hhs.onc.dcdt.compress.utils.ArchiveUtils.ZipArchiveEntryPairTransformer;
+import gov.hhs.onc.dcdt.test.impl.AbstractToolUnitTests;
+import gov.hhs.onc.dcdt.utils.ToolArrayUtils;
+import java.util.Collection;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.beans.factory.annotation.Value;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+@Test(groups =
{ "dcdt.test.unit.compress.all", "dcdt.test.unit.compress.utils.all", "dcdt.test.unit.compress.utils.archive"
})
+public class ArchiveUtilsUnitTests extends AbstractToolUnitTests {
+ @Value("${dcdt.test.archive.entry.1.name}")
+ private String testArchiveEntry1Name;
+
+ @Value("${dcdt.test.archive.entry.1.value}")
+ private String testArchiveEntry1Value;
+
+ @Value("${dcdt.test.archive.entry.2.name}")
+ private String testArchiveEntry2Name;
+
+ @Value("${dcdt.test.archive.entry.2.value}")
+ private String testArchiveEntry2Value;
+
+ private Collection<Pair<ZipArchiveEntry, byte[]>> testEntryPairs;
+ private byte[] testArchiveData;
+
+ // @formatter:off
+ /*
+ @Test(dependsOnMethods = { "testWriteArchive" })
+ public void testReadArchive() throws ArchiveException {
+ List<Pair<ZipArchiveEntry, byte[]>> testEntryPairsRead =
ArchiveUtils.readArchive(ArchiveType.ZIP, new
ByteArrayInputStream(this.testArchiveData));
+ Pair<ZipArchiveEntry, byte[]> testEntryPair, testEntryPairRead;
+ String testEntryName;
+
+ Assert.assertEquals(testEntryPairsRead.size(),
this.testEntryPairs.size(), "Number of archive entries does not match.");
+
+ for (int a = 0; a < this.testEntryPairs.size(); a++) {
+ Assert.assertEquals((testEntryPairRead =
testEntryPairsRead.get(a)).getLeft().getName(),
+ (testEntryName = (testEntryPair =
this.testEntryPairs.get(a)).getLeft().getName()), "Archive entry names do
not match.");
+ Assert.assertEquals(testEntryPairRead.getRight(),
testEntryPair.getRight(),
+ String.format("Archive entry (name=%s) data does not
match.", testEntryName));
+ }
+ }
+ */
+ // @formatter:on
+
+ @SuppressWarnings({ "unchecked" })
+ @Test
+ public void testWriteArchive() throws ArchiveException {
+ Assert
+ .assertTrue(
+ ((this.testArchiveData =
+ ArchiveUtils.writeArchive(
+ ArchiveType.ZIP,
+ (this.testEntryPairs =
+ CollectionUtils.collect(ToolArrayUtils.asList(
+ new
ImmutablePair<>(this.testArchiveEntry1Name,
this.testArchiveEntry1Value.getBytes()), new ImmutablePair<>(
+ this.testArchiveEntry2Name,
this.testArchiveEntry2Value.getBytes())),
ZipArchiveEntryPairTransformer.INSTANCE)))).length > 0),
+ "No archive data written.");
+ }
+}
=======================================
--- /dev/null
+++ /dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/HttpHeaderNames.java Sun
May 4 20:51:50 2014 UTC
@@ -0,0 +1,13 @@
+package gov.hhs.onc.dcdt.web;
+
+public final class HttpHeaderNames {
+ public final static String DELIM_HEADER_VALUE = "; ";
+ public final static String DELIM_HEADER_VALUE_PARAM = "=";
+
+ public final static String HEADER_NAME_CONTENT_DISPOSITION
= "Content-Disposition";
+ public final static String HEADER_VALUE_CONTENT_DISPOSITION_ATTACHMENT
= "attachment";
+ public final static String
HEADER_VALUE_PARAM_NAME_CONTENT_DISPOSITION_FILENAME = "filename";
+
+ private HttpHeaderNames() {
+ }
+}
=======================================
--- /dcdt-core/pom.xml Wed Apr 30 19:02:53 2014 UTC
+++ /dcdt-core/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -65,7 +65,6 @@
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -109,6 +108,10 @@
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
</dependency>
=======================================
--- /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/PemType.java Tue Mar
25 18:00:58 2014 UTC
+++ /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/PemType.java Sun May
4 20:51:50 2014 UTC
@@ -5,8 +5,7 @@
import java.security.cert.X509Certificate;

public enum PemType implements CryptographyTypeIdentifier {
- X509_PUBLIC_KEY("PUBLIC KEY", PublicKey.class), PKCS8_PRIVATE_KEY("RSA
PRIVATE KEY", PrivateKey.class), X509_CERTIFICATE("X.509 CERTIFICATE",
- X509Certificate.class);
+ PUBLIC_KEY("PUBLIC KEY", PublicKey.class), PRIVATE_KEY("PRIVATE KEY",
PrivateKey.class), X509_CERTIFICATE("X.509 CERTIFICATE",
X509Certificate.class);

private final String id;
private final Class<?> type;
=======================================
--- /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/keys/KeyAlgorithm.java
Wed Apr 23 18:24:11 2014 UTC
+++ /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/keys/KeyAlgorithm.java
Sun May 4 20:51:50 2014 UTC
@@ -3,30 +3,38 @@
import gov.hhs.onc.dcdt.crypto.CryptographyAlgorithmIdentifier;
import gov.hhs.onc.dcdt.dns.DnsKeyAlgorithmType;
import gov.hhs.onc.dcdt.net.mime.CoreContentTypes;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.springframework.util.MimeType;

public enum KeyAlgorithm implements CryptographyAlgorithmIdentifier {
- RSA("RSA", PKCSObjectIdentifiers.rsaEncryption, "X.509", "PKCS#8",
512, new MimeType(CoreContentTypes.APP_TYPE, "pkcs8"),
DnsKeyAlgorithmType.RSASHA1);
+ RSA("RSA", PKCSObjectIdentifiers.rsaEncryption, "X.509",
X509EncodedKeySpec.class, "PKCS#8", PKCS8EncodedKeySpec.class, 512, new
MimeType(
+ CoreContentTypes.APP_TYPE, "pkcs8"), DnsKeyAlgorithmType.RSASHA1);

private final String id;
private final ASN1ObjectIdentifier oid;
private final AlgorithmIdentifier algId;
private final String publicFormat;
+ private final Class<? extends EncodedKeySpec> publicKeySpecClass;
private final String privateFormat;
+ private final Class<? extends EncodedKeySpec> privateKeySpecClass;
private final int keySizeMin;
private final MimeType contentType;
private final DnsKeyAlgorithmType dnsAlgType;

- private KeyAlgorithm(String id, ASN1ObjectIdentifier oid, String
publicFormat, String privateFormat, int keySizeMin, MimeType contentType,
- DnsKeyAlgorithmType dnsAlgType) {
+ private KeyAlgorithm(String id, ASN1ObjectIdentifier oid, String
publicFormat, Class<? extends EncodedKeySpec> publicKeySpecClass, String
privateFormat,
+ Class<? extends EncodedKeySpec> privateKeySpecClass, int
keySizeMin, MimeType contentType, DnsKeyAlgorithmType dnsAlgType) {
this.id = id;
this.oid = oid;
this.algId = new AlgorithmIdentifier(this.oid);
this.publicFormat = publicFormat;
+ this.publicKeySpecClass = publicKeySpecClass;
this.privateFormat = privateFormat;
+ this.privateKeySpecClass = privateKeySpecClass;
this.keySizeMin = keySizeMin;
this.contentType = contentType;
this.dnsAlgType = dnsAlgType;
@@ -48,6 +56,10 @@
public String getFormat(KeyType keyType) {
return (keyType == KeyType.PUBLIC) ? this.getPublicFormat() :
this.getPrivateFormat();
}
+
+ public Class<? extends EncodedKeySpec> getKeySpecClass(KeyType
keyType) {
+ return (keyType == KeyType.PUBLIC) ?
this.getPublicKeySpecClass() : this.getPrivateKeySpecClass();
+ }

@Override
public String getId() {
@@ -66,8 +78,16 @@
public String getPublicFormat() {
return this.publicFormat;
}
+
+ public Class<? extends EncodedKeySpec> getPublicKeySpecClass() {
+ return this.publicKeySpecClass;
+ }

public String getPrivateFormat() {
return this.privateFormat;
}
+
+ public Class<? extends EncodedKeySpec> getPrivateKeySpecClass() {
+ return this.privateKeySpecClass;
+ }
}
=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CertificateUtils.java
Thu Apr 3 02:16:49 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CertificateUtils.java
Sun May 4 20:51:50 2014 UTC
@@ -53,7 +53,7 @@
public static X509Certificate readCertificate(byte[] data,
CertificateType certType, DataEncoding dataEnc) throws
CryptographyException {
try {
if (dataEnc == DataEncoding.PEM) {
- data = PemUtils.writePemContent(certType.getId(), data);
+ data =
PemUtils.writePemContent(CryptographyUtils.findTypeId(PemType.class,
certType.getType()), data);
}

return (X509Certificate)
getCertificateFactory(certType).generateCertificate(new
ByteArrayInputStream(data));
=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CryptographyUtils.java
Tue Apr 22 01:53:59 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CryptographyUtils.java
Sun May 4 20:51:50 2014 UTC
@@ -64,7 +64,7 @@
@Nullable
public static <U extends Enum<U> & CryptographyTypeIdentifier> U
findTypeId(Class<U> idEnumClass, Class<?> type) {
for (U idEnum : EnumSet.allOf(idEnumClass)) {
- if (ToolClassUtils.isAssignable(idEnum.getType(), type)) {
+ if (ToolClassUtils.isAssignable(type, idEnum.getType())) {
return idEnum;
}
}
=======================================
--- /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/KeyUtils.java
Tue Mar 25 18:00:58 2014 UTC
+++ /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/KeyUtils.java
Sun May 4 20:51:50 2014 UTC
@@ -16,65 +16,18 @@
import java.io.Reader;
import java.io.Writer;
import java.security.Key;
+import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.KeyRep;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SerializationException;
import org.apache.commons.lang3.SerializationUtils;

public abstract class KeyUtils {
- public static PublicKey readPublicKey(InputStream inStream,
KeyAlgorithm keyAlg, DataEncoding dataEnc) throws CryptographyException {
- return (PublicKey) readKey(KeyType.PUBLIC, inStream, keyAlg,
dataEnc);
- }
-
- public static PublicKey readPublicKey(Reader reader, KeyAlgorithm
keyAlg, DataEncoding dataEnc) throws CryptographyException {
- return (PublicKey) readKey(KeyType.PUBLIC, reader, keyAlg,
dataEnc);
- }
-
- public static PublicKey readPublicKey(byte[] data, KeyAlgorithm
keyAlg, DataEncoding dataEnc) throws CryptographyException {
- return (PublicKey) readKey(KeyType.PUBLIC, data, keyAlg, dataEnc);
- }
-
- public static byte[] writePublicKey(PublicKey publicKey, DataEncoding
dataEnc) throws CryptographyException {
- return writeKey(publicKey, dataEnc);
- }
-
- public static void writePublicKey(OutputStream outStream, PublicKey
publicKey, DataEncoding dataEnc) throws CryptographyException {
- writeKey(outStream, publicKey, dataEnc);
- }
-
- public static void writePublicKey(Writer writer, PublicKey publicKey,
DataEncoding dataEnc) throws CryptographyException {
- writeKey(writer, publicKey, dataEnc);
- }
-
- public static PrivateKey readPrivateKey(InputStream inStream,
KeyAlgorithm keyAlg, DataEncoding dataEnc) throws CryptographyException {
- return (PrivateKey) readKey(KeyType.PRIVATE, inStream, keyAlg,
dataEnc);
- }
-
- public static PrivateKey readPrivateKey(Reader reader, KeyAlgorithm
keyAlg, DataEncoding dataEnc) throws CryptographyException {
- return (PrivateKey) readKey(KeyType.PRIVATE, reader, keyAlg,
dataEnc);
- }
-
- public static PrivateKey readPrivateKey(byte[] data, KeyAlgorithm
keyAlg, DataEncoding dataEnc) throws CryptographyException {
- return (PrivateKey) readKey(KeyType.PRIVATE, data, keyAlg,
dataEnc);
- }
-
- public static byte[] writePrivateKey(PrivateKey privateKey,
DataEncoding dataEnc) throws CryptographyException {
- return writeKey(privateKey, dataEnc);
- }
-
- public static void writePrivateKey(OutputStream outStream, PrivateKey
privateKey, DataEncoding dataEnc) throws CryptographyException {
- writeKey(outStream, privateKey, dataEnc);
- }
-
- public static void writePrivateKey(Writer writer, PrivateKey
privateKey, DataEncoding dataEnc) throws CryptographyException {
- writeKey(writer, privateKey, dataEnc);
- }
-
public static Key readKey(KeyType keyType, InputStream inStream,
KeyAlgorithm keyAlg, DataEncoding dataEnc) throws CryptographyException {
return readKey(keyType, new InputStreamReader(inStream), keyAlg,
dataEnc);
}
@@ -83,23 +36,22 @@
try {
return readKey(keyType, IOUtils.toByteArray(reader), keyAlg,
dataEnc);
} catch (IOException e) {
- throw new KeyException(String.format(
- "Unable to read key instance (type=%s) for key algorithm
(id=%s, format=%s, providerName=%s) from reader (class=%s).",
keyType.getId(),
- keyAlg.getId(), keyAlg.getPrivateFormat(),
CryptographyUtils.PROVIDER_NAME, ToolClassUtils.getName(reader)), e);
+ throw new KeyException(String.format("Unable to read key
(type=%s, algId=%s, format=%s, providerName=%s) from reader (class=%s).",
keyType.getId(),
+ keyAlg.getId(), keyAlg.getFormat(keyType),
CryptographyUtils.PROVIDER_NAME, ToolClassUtils.getName(reader)), e);
}
}

public static Key readKey(KeyType keyType, byte[] data, KeyAlgorithm
keyAlg, DataEncoding dataEnc) throws CryptographyException {
try {
if (dataEnc == DataEncoding.PEM) {
- data = PemUtils.writePemContent(keyType.getId(), data);
+ data =
PemUtils.writePemContent(CryptographyUtils.findTypeId(PemType.class,
keyType.getType()), data);
}

- return (Key)
SerializationUtils.deserialize(SerializationUtils.serialize(new
KeyRep(keyType.getKeyRepType(), keyAlg.getId(), keyAlg
- .getFormat(keyType), data)));
+ return ((Key)
SerializationUtils.deserialize(SerializationUtils.serialize(new
KeyRep(keyType.getKeyRepType(), keyAlg.getId(), keyAlg
+ .getFormat(keyType), data))));
} catch (SerializationException e) {
- throw new KeyException(String.format("Unable to read key
instance (type=%s) for key algorithm (id=%s, format=%s, providerName=%s)
from data.",
- keyType.getId(), keyAlg.getId(),
keyAlg.getPrivateFormat(), CryptographyUtils.PROVIDER_NAME), e);
+ throw new KeyException(String.format("Unable to read key
(type=%s, algId=%s, format=%s, providerName=%s) from data.",
keyType.getId(),
+ keyAlg.getId(), keyAlg.getFormat(keyType),
CryptographyUtils.PROVIDER_NAME), e);
}
}

@@ -116,17 +68,28 @@
}

public static <T extends Key> void writeKey(Writer writer, T key,
DataEncoding dataEnc) throws CryptographyException {
- byte[] data = key.getEncoded();
+ Class<? extends Key> keyClass = key.getClass();
+ KeyType keyType = CryptographyUtils.findTypeId(KeyType.class,
keyClass);
+ KeyAlgorithm keyAlg = CryptographyUtils.findId(KeyAlgorithm.class,
key.getAlgorithm());
+ // noinspection ConstantConditions
+ Class<? extends EncodedKeySpec> keySpecClass =
keyAlg.getKeySpecClass(keyType);

try {
+ // noinspection ConstantConditions
+ byte[] data =
keySpecClass.cast(getKeyFactory(keyAlg).getKeySpec(key,
keySpecClass)).getEncoded();
+
if (dataEnc == DataEncoding.PEM) {
- PemUtils.writePemContent(writer,
CryptographyUtils.findTypeId(PemType.class, key.getClass()), data);
+ PemUtils.writePemContent(writer,
CryptographyUtils.findTypeId(PemType.class, keyClass), data);
} else {
IOUtils.write(data, writer);
}
- } catch (IOException e) {
- throw new KeyException(String.format("Unable to write key
instance (type=%s, class=%s) to writer (class=%s).",
- CryptographyUtils.findTypeId(KeyType.class,
key.getClass()), ToolClassUtils.getClass(key),
ToolClassUtils.getName(writer)), e);
+
+ writer.flush();
+ } catch (InvalidKeySpecException | IOException e) {
+ throw new KeyException(String.format(
+ "Unable to write key (type=%s, algId=%s, format=%s,
keySpecClass=%s, class=%s, providerName=%s) to writer (class=%s).", keyType,
+ keyAlg.getId(), keyAlg.getFormat(keyType),
ToolClassUtils.getName(keySpecClass), ToolClassUtils.getName(keyClass),
+ CryptographyUtils.PROVIDER_NAME,
ToolClassUtils.getName(writer)), e);
}
}

@@ -134,7 +97,16 @@
try {
return
CryptographyUtils.PROVIDER_HELPER.createKeyPairGenerator(keyAlg.getId());
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
- throw new KeyException(String.format("Unable to get key pair
generator instance for key algorithm (id=%s, providerName=%s).",
keyAlg.getId(),
+ throw new KeyException(String.format("Unable to get key pair
generator for key algorithm (id=%s, providerName=%s).", keyAlg.getId(),
+ CryptographyUtils.PROVIDER_NAME), e);
+ }
+ }
+
+ public static KeyFactory getKeyFactory(KeyAlgorithm keyAlg) throws
CryptographyException {
+ try {
+ return
CryptographyUtils.PROVIDER_HELPER.createKeyFactory(keyAlg.getId());
+ } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+ throw new KeyException(String.format("Unable to get key
factory for key algorithm (id=%s, providerName=%s).", keyAlg.getId(),
CryptographyUtils.PROVIDER_NAME), e);
}
}
=======================================
--- /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/PemUtils.java
Tue Mar 25 18:00:58 2014 UTC
+++ /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/PemUtils.java
Sun May 4 20:51:50 2014 UTC
@@ -38,20 +38,12 @@
}

public static PemObject readPemObject(Reader reader) throws
CryptographyException {
- try (PEMParser pemParser = new PEMParser(reader)) {
- return pemParser.readPemObject();
+ try {
+ return new PEMParser(reader).readPemObject();
} catch (IOException e) {
throw new CryptographyException(String.format("Unable to read
PEM object from reader (class=%s).", ToolClassUtils.getName(reader)), e);
}
}
-
- public static byte[] writePemContent(String pemType, byte[] data)
throws CryptographyException {
- return writePemObject(pemType, data).getContent();
- }
-
- public static PemObject writePemObject(String pemType, byte[] data) {
- return new PemObject(pemType, data);
- }

public static byte[] writePemContent(PemType pemType, byte[] data)
throws CryptographyException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
@@ -74,11 +66,14 @@
}

public static void writePemObject(Writer writer, PemObject pemObj)
throws CryptographyException {
- try (PemWriter pemWriter = new PemWriter(writer)) {
+ PemWriter pemWriter = new PemWriter(writer);
+
+ try {
pemWriter.writeObject(pemObj);
pemWriter.flush();
} catch (IOException e) {
- throw new CryptographyException(String.format("Unable to write
PEM object to writer (class=%s).", ToolClassUtils.getName(writer)), e);
+ throw new CryptographyException(String.format("Unable to write
PEM object (type=%s) to writer (class=%s).", pemObj.getType(),
+ ToolClassUtils.getName(writer)), e);
}
}
}
=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtils.java
Wed Apr 30 07:37:27 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtils.java
Sun May 4 20:51:50 2014 UTC
@@ -86,6 +86,15 @@
signerInfo = signerInfoMap.get(signerId);

for (X509CertificateHolder certHolder :
((Collection<X509CertificateHolder>) signedCerts.getMatches(signerId))) {
+ try {
+ signerCertMap.put(signerId, new
CertificateInfoImpl(CertificateUtils.CERT_CONV.getCertificate(certHolder)));
+ } catch (CertificateException e) {
+ throw new ToolSmimeException(String.format("Unable to
verify mail signed data signer (id={issuer=%s, serialNum=%s}).",
+ signerId.getIssuer(), new
CertificateSerialNumberImpl(signerId.getSerialNumber())), e);
+ }
+
+ // @formatter:off
+ /*
try {
if
(signerInfo.verify(signerInfoVerifierBuilder.build(certHolder))) {
signerCertMap.put(signerId, new
CertificateInfoImpl(CertificateUtils.CERT_CONV.getCertificate(certHolder)));
@@ -97,6 +106,8 @@
"Unable to verify mail signed data signer
(id={issuer=%s, serialNum=%s}) certificate (subj={%s}).",
signerId.getIssuer(),
new
CertificateSerialNumberImpl(signerId.getSerialNumber()),
certHolder.getSubject()), e);
}
+ */
+ // @formatter:on
}

if (!signerCertMap.containsKey(signerId)) {
=======================================
---
/dcdt-core/src/test/java/gov/hhs/onc/dcdt/crypto/keys/KeyInfoUnitTests.java
Wed Mar 12 19:45:48 2014 UTC
+++
/dcdt-core/src/test/java/gov/hhs/onc/dcdt/crypto/keys/KeyInfoUnitTests.java
Sun May 4 20:51:50 2014 UTC
@@ -5,6 +5,8 @@
import gov.hhs.onc.dcdt.crypto.keys.impl.KeyInfoImpl;
import gov.hhs.onc.dcdt.crypto.utils.KeyUtils;
import gov.hhs.onc.dcdt.test.impl.AbstractToolUnitTests;
+import java.security.PrivateKey;
+import java.security.PublicKey;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.testng.Assert;
@@ -44,7 +46,7 @@
@BeforeClass
public void buildKeyInfo() throws CryptographyException {
this.testKeyInfo =
- new
KeyInfoImpl(KeyUtils.readPublicKey(Base64.decodeBase64(this.testKeysPublicKeyStr),
KeyAlgorithm.RSA, DataEncoding.DER),
-
KeyUtils.readPrivateKey(Base64.decodeBase64(this.testKeysPrivateKeyStr),
KeyAlgorithm.RSA, DataEncoding.DER));
+ new KeyInfoImpl(((PublicKey) KeyUtils.readKey(KeyType.PUBLIC,
Base64.decodeBase64(this.testKeysPublicKeyStr), KeyAlgorithm.RSA,
DataEncoding.DER)),
+ ((PrivateKey) KeyUtils.readKey(KeyType.PRIVATE,
Base64.decodeBase64(this.testKeysPrivateKeyStr), KeyAlgorithm.RSA,
DataEncoding.DER)));
}
}
=======================================
---
/dcdt-core/src/test/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtilsFunctionalTests.java
Fri Apr 18 16:09:01 2014 UTC
+++
/dcdt-core/src/test/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtilsFunctionalTests.java
Sun May 4 20:51:50 2014 UTC
@@ -10,6 +10,7 @@
import gov.hhs.onc.dcdt.crypto.credentials.impl.CredentialInfoImpl;
import gov.hhs.onc.dcdt.crypto.keys.KeyAlgorithm;
import gov.hhs.onc.dcdt.crypto.keys.KeyInfo;
+import gov.hhs.onc.dcdt.crypto.keys.KeyType;
import gov.hhs.onc.dcdt.crypto.keys.impl.KeyInfoImpl;
import gov.hhs.onc.dcdt.crypto.utils.CertificateUtils;
import gov.hhs.onc.dcdt.crypto.utils.KeyUtils;
@@ -34,6 +35,8 @@
import java.io.IOException;
import java.net.InetAddress;
import java.nio.charset.Charset;
+import java.security.PrivateKey;
+import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -182,8 +185,8 @@
@BeforeClass
public void buildSignerCredentialInfo() throws CryptographyException {
KeyInfo testSignerKeyInfo =
- new
KeyInfoImpl(KeyUtils.readPublicKey(Base64.decodeBase64(this.testPublicKeyStr),
KeyAlgorithm.RSA, DataEncoding.DER), KeyUtils.readPrivateKey(
- Base64.decodeBase64(this.testPrivateKeyStr),
KeyAlgorithm.RSA, DataEncoding.DER));
+ new KeyInfoImpl(((PublicKey) KeyUtils.readKey(KeyType.PUBLIC,
Base64.decodeBase64(this.testPublicKeyStr), KeyAlgorithm.RSA,
DataEncoding.DER)),
+ ((PrivateKey) KeyUtils.readKey(KeyType.PRIVATE,
Base64.decodeBase64(this.testPrivateKeyStr), KeyAlgorithm.RSA,
DataEncoding.DER)));
CertificateInfo testSignerCertInfo =
new
CertificateInfoImpl(CertificateUtils.readCertificate(Base64.decodeBase64(this.testCertStr),
CertificateType.X509, DataEncoding.DER));
this.testSignerCredInfo = new
CredentialInfoImpl(testSignerKeyInfo, testSignerCertInfo);
=======================================
--- /dcdt-core/src/test/resources/META-INF/core/core-test.properties Fri
May 2 03:12:01 2014 UTC
+++ /dcdt-core/src/test/resources/META-INF/core/core-test.properties Sun
May 4 20:51:50 2014 UTC
@@ -1,3 +1,11 @@
+#====================================================================================================
+# ARCHIVES
+#====================================================================================================
+dcdt.test.archive.entry.1.name=entry1.txt
+dcdt.test.archive.entry.1.value=entry1value
+dcdt.test.archive.entry.2.name=entry2/entry2.txt
+dcdt.test.archive.entry.2.value=entry2value
+

#====================================================================================================
# PROPERTIES

#====================================================================================================
=======================================
--- /dcdt-parent/pom.xml Fri May 2 21:53:01 2014 UTC
+++ /dcdt-parent/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -216,7 +216,6 @@
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.1</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -298,6 +297,11 @@
<version>4.0</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>1.8</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
<version>2.1.1</version>
=======================================
--- /dcdt-service-core/pom.xml Wed Apr 30 19:02:53 2014 UTC
+++ /dcdt-service-core/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -59,7 +59,6 @@
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
=======================================
--- /dcdt-service-dns/pom.xml Wed Apr 30 19:02:53 2014 UTC
+++ /dcdt-service-dns/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -66,7 +66,6 @@
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
=======================================
--- /dcdt-service-ldap/pom.xml Wed Apr 30 19:02:53 2014 UTC
+++ /dcdt-service-ldap/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -66,7 +66,6 @@
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
=======================================
--- /dcdt-service-mail/pom.xml Wed Apr 30 19:02:53 2014 UTC
+++ /dcdt-service-mail/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -66,7 +66,6 @@
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
=======================================
---
/dcdt-service-mail/src/main/resources/META-INF/spring/spring-service-mail.xml
Tue Apr 29 00:09:36 2014 UTC
+++
/dcdt-service-mail/src/main/resources/META-INF/spring/spring-service-mail.xml
Sun May 4 20:51:50 2014 UTC
@@ -113,7 +113,7 @@
<amq:systemUsage>
<amq:systemUsage>
<amq:memoryUsage>
- <amq:memoryUsage limit="64M"/>
+ <amq:memoryUsage limit="256M"/>
</amq:memoryUsage>
</amq:systemUsage>
</amq:systemUsage>
@@ -276,8 +276,7 @@
p:className="RemoteDelivery">
<beans:property
name="initParameters">
<util:map>
- <beans:entry
key="delayTime" value="5 minutes"/>
- <beans:entry
key="deliveryThreads" value="#{ taskExecServiceMail.maxPoolSize }"/>
+ <beans:entry
key="deliveryThreads" value="20"/>
<beans:entry
key="maxRetries" value="0"/>
</util:map>
</beans:property>
@@ -345,7 +344,9 @@

=====================================================================================================-->
<beans:bean id="mailSpooler"
class="gov.hhs.onc.dcdt.service.mail.james.impl.ToolMailSpooler">
<beans:property name="configBean">
- <beans:bean parent="configBeanMailSpoolerImpl"/>
+ <beans:bean parent="configBeanMailSpoolerImpl"
+ p:dequeueThreads="20"
+ p:threads="100"/>
</beans:property>
</beans:bean>
<beans:alias name="mailSpooler" alias="mailspooler"/>
=======================================
--- /dcdt-web/pom.xml Fri May 2 21:53:01 2014 UTC
+++ /dcdt-web/pom.xml Sun May 4 20:51:50 2014 UTC
@@ -121,7 +121,6 @@
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
=======================================
---
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/AbstractToolController.java
Wed Feb 26 18:58:16 2014 UTC
+++
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/AbstractToolController.java
Sun May 4 20:51:50 2014 UTC
@@ -1,14 +1,22 @@
package gov.hhs.onc.dcdt.web.controller.impl;

import gov.hhs.onc.dcdt.beans.impl.AbstractToolBean;
+import gov.hhs.onc.dcdt.utils.ToolStringUtils;
+import gov.hhs.onc.dcdt.web.HttpHeaderNames;
+import gov.hhs.onc.dcdt.web.ToolWebException;
import gov.hhs.onc.dcdt.web.controller.ToolController;
+import java.io.IOException;
import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.convert.ConversionService;
+import org.springframework.util.MimeType;

public abstract class AbstractToolController extends AbstractToolBean
implements ToolController, MessageSourceAware {
@Resource(name = "conversionService")
@@ -20,6 +28,25 @@
protected MessageSource msgSource;

protected AbstractApplicationContext appContext;
+
+ protected static void buildFileResponse(HttpServletResponse
servletResp, String fileName, MimeType fileContentType, byte[] fileData)
+ throws ToolWebException {
+ ServletOutputStream servletOutStream;
+
+ try {
+
servletResp.setHeader(HttpHeaderNames.HEADER_NAME_CONTENT_DISPOSITION,
(HttpHeaderNames.HEADER_VALUE_CONTENT_DISPOSITION_ATTACHMENT
+ + HttpHeaderNames.DELIM_HEADER_VALUE +
HttpHeaderNames.HEADER_VALUE_PARAM_NAME_CONTENT_DISPOSITION_FILENAME
+ + HttpHeaderNames.DELIM_HEADER_VALUE_PARAM +
ToolStringUtils.quote(fileName)));
+ servletResp.setContentType(fileContentType.toString());
+ servletResp.setContentLength(fileData.length);
+
+ IOUtils.write(fileData, (servletOutStream =
servletResp.getOutputStream()));
+ servletOutStream.flush();
+ } catch (IOException e) {
+ throw new ToolWebException(String.format("Unable to write file
(name=%s, contentType={%s}) data (len=%d) to servlet output stream.",
fileName,
+ fileContentType, fileData.length), e);
+ }
+ }

@Override
public void setApplicationContext(ApplicationContext appContext)
throws BeansException {
=======================================
---
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/AdminController.java
Sat Feb 8 18:10:52 2014 UTC
+++
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/AdminController.java
Sun May 4 20:51:50 2014 UTC
@@ -1,7 +1,35 @@
package gov.hhs.onc.dcdt.web.controller.impl;

+import gov.hhs.onc.dcdt.beans.utils.ToolBeanFactoryUtils;
+import gov.hhs.onc.dcdt.compress.ArchiveType;
+import gov.hhs.onc.dcdt.compress.utils.ArchiveUtils;
+import
gov.hhs.onc.dcdt.compress.utils.ArchiveUtils.ZipArchiveEntryPairTransformer;
+import gov.hhs.onc.dcdt.config.instance.InstanceConfig;
+import gov.hhs.onc.dcdt.crypto.CryptographyException;
+import gov.hhs.onc.dcdt.crypto.DataEncoding;
+import gov.hhs.onc.dcdt.crypto.certs.CertificateInfo;
+import gov.hhs.onc.dcdt.crypto.credentials.CredentialInfo;
+import gov.hhs.onc.dcdt.crypto.keys.KeyInfo;
+import gov.hhs.onc.dcdt.crypto.utils.CertificateUtils;
+import gov.hhs.onc.dcdt.crypto.utils.KeyUtils;
+import gov.hhs.onc.dcdt.testcases.discovery.DiscoveryTestcase;
+import
gov.hhs.onc.dcdt.testcases.discovery.DiscoveryTestcase.DiscoveryTestcaseCredentialsExtractor;
+import
gov.hhs.onc.dcdt.testcases.discovery.credentials.DiscoveryTestcaseCredential;
+import
gov.hhs.onc.dcdt.testcases.discovery.credentials.DiscoveryTestcaseCredential.DiscoveryTestcaseCredentialTypePredicate;
+import gov.hhs.onc.dcdt.utils.ToolIteratorUtils;
+import gov.hhs.onc.dcdt.web.ToolWebException;
import gov.hhs.onc.dcdt.web.controller.DisplayController;
import gov.hhs.onc.dcdt.web.view.RequestView;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map.Entry;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IteratorUtils;
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -10,6 +38,78 @@
@Controller("adminController")
@DisplayController
public class AdminController extends AbstractToolController {
+ private final static String FILE_NAME_SUFFIX_CREDS_ARCHIVE = "_creds";
+ private final static String FILE_NAME_SUFFIX_CRED_KEY = "_key";
+
+ @RequestMapping(value = { "/admin/instance/creds" }, method = {
RequestMethod.GET })
+ public void downloadInstanceCredentials(HttpServletResponse
servletResp) throws ToolWebException {
+ InstanceConfig instanceConfig =
ToolBeanFactoryUtils.getBeanOfType(this.appContext, InstanceConfig.class);
+
+ // noinspection ConstantConditions
+ if (!instanceConfig.isConfigured()) {
+ throw new ToolWebException("Instance configuration is not
set.");
+ }
+
+ EnumSet<DataEncoding> dataEncs = EnumSet.allOf(DataEncoding.class);
+ List<DiscoveryTestcaseCredential> creds =
+
IteratorUtils.toList(ToolIteratorUtils.chainedIterator(CollectionUtils.collect(
+ ToolBeanFactoryUtils.getBeansOfType(this.appContext,
DiscoveryTestcase.class), DiscoveryTestcaseCredentialsExtractor.INSTANCE)));
+
creds.add(CollectionUtils.find(ToolBeanFactoryUtils.getBeansOfType(this.appContext,
DiscoveryTestcaseCredential.class),
+ DiscoveryTestcaseCredentialTypePredicate.INSTANCE_CA));
+
+ List<Entry<String, byte[]>> credEntryDescPairs = new
ArrayList<>(creds.size() * 3);
+ String credName;
+ CredentialInfo credInfo;
+ KeyInfo keyInfo;
+ CertificateInfo certInfo;
+ X509Certificate cert;
+
+ for (DiscoveryTestcaseCredential cred : creds) {
+ if (!cred.hasCredentialInfo()) {
+ continue;
+ }
+
+ credName = cred.getName();
+
+ // noinspection ConstantConditions
+ if ((credInfo = cred.getCredentialInfo()).hasKeyDescriptor()
&& (keyInfo = credInfo.getKeyDescriptor()).hasPrivateKey()) {
+ for (DataEncoding dataEnc : dataEncs) {
+ try {
+ credEntryDescPairs.add(new
ImmutablePair<>((credName + FILE_NAME_SUFFIX_CRED_KEY +
dataEnc.getFileExtension()), KeyUtils.writeKey(
+ keyInfo.getPrivateKey(), dataEnc)));
+ } catch (CryptographyException e) {
+ throw new ToolWebException(String.format("Unable
to write Discovery credential (name=%s) private key data.", credName), e);
+ }
+ }
+ }
+
+ // noinspection ConstantConditions
+ if ((certInfo =
credInfo.getCertificateDescriptor()).hasCertificate()) {
+ cert = certInfo.getCertificate();
+
+ for (DataEncoding dataEnc : dataEncs) {
+ try {
+ credEntryDescPairs.add(new
ImmutablePair<>((credName + dataEnc.getFileExtension()),
CertificateUtils.writeCertificate(
+ certInfo.getCertificate(), dataEnc)));
+ } catch (CryptographyException e) {
+ // noinspection ConstantConditions
+ throw new ToolWebException(String.format(
+ "Unable to write Discovery credential
(name=%s) certificate (subj={%s}, serialNum=%s, issuer={%s}) data.",
credName, cert
+ .getSubjectX500Principal().getName(),
certInfo.getSerialNumber(), cert.getIssuerX500Principal().getName()), e);
+ }
+ }
+ }
+ }
+
+ try {
+ buildFileResponse(servletResp, (instanceConfig.getDomainName()
+ FILE_NAME_SUFFIX_CREDS_ARCHIVE + ArchiveType.ZIP.getFileExtension()),
+ ArchiveType.ZIP.getContentType(),
+ ArchiveUtils.writeArchive(ArchiveType.ZIP,
CollectionUtils.collect(credEntryDescPairs,
ZipArchiveEntryPairTransformer.INSTANCE)));
+ } catch (ArchiveException e) {
+ throw new ToolWebException("Unable to write Discovery
credentials archive data.", e);
+ }
+ }
+
@RequestMapping(value = { "/admin/login" }, method = {
RequestMethod.GET })
@RequestView("admin-login")
public ModelAndView displayAdminLogin() {
=======================================
---
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/DiscoveryController.java
Wed Apr 23 18:24:11 2014 UTC
+++
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/controller/impl/DiscoveryController.java
Sun May 4 20:51:50 2014 UTC
@@ -9,19 +9,13 @@
import gov.hhs.onc.dcdt.testcases.discovery.DiscoveryTestcase;
import
gov.hhs.onc.dcdt.testcases.discovery.credentials.DiscoveryTestcaseCredential;
import
gov.hhs.onc.dcdt.testcases.discovery.credentials.DiscoveryTestcaseCredential.DiscoveryTestcaseCredentialTypePredicate;
-import gov.hhs.onc.dcdt.utils.ToolStringUtils;
import gov.hhs.onc.dcdt.web.ToolWebException;
import gov.hhs.onc.dcdt.web.controller.DisplayController;
import gov.hhs.onc.dcdt.web.view.RequestView;
-import java.io.IOException;
-import java.nio.charset.Charset;
import java.security.cert.X509Certificate;
import java.util.List;
-import javax.annotation.Resource;
-import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -31,13 +25,6 @@
@Controller("discoveryController")
@DisplayController
public class DiscoveryController extends AbstractToolController {
- private final static String HEADER_NAME_CONTENT_DISPOSITION
= "Content-Disposition";
-
- private final static String
HEADER_VALUE_PREFIX_CONTENT_DISPOSITION_ANCHOR = "attachment; filename=";
-
- @Resource(name = "charsetUtf8")
- private Charset anchorEnc;
-
@RequestMapping(value = { "/discovery/anchor" }, method = {
RequestMethod.GET })
public void downloadAnchor(HttpServletResponse servletResp) throws
ToolWebException {
DiscoveryTestcaseCredential anchorCred =
@@ -54,25 +41,15 @@
}

X509Certificate anchorCert = anchorCertInfo.getCertificate();
- byte[] anchorCertData;
- ServletOutputStream servletOutStream;

try {
- anchorCertData = CertificateUtils.writeCertificate(anchorCert,
DataEncoding.DER);
-
- servletResp.setHeader(HEADER_NAME_CONTENT_DISPOSITION,
- (HEADER_VALUE_PREFIX_CONTENT_DISPOSITION_ANCHOR +
ToolStringUtils.quote(anchorCred.getName() +
DataEncoding.DER.getFileExtension())));
- servletResp.setContentLength(anchorCertData.length);
// noinspection ConstantConditions
-
servletResp.setContentType(anchorCertInfo.getCertificateType().getContentType().toString());
-
- IOUtils.write(anchorCertData, (servletOutStream =
servletResp.getOutputStream()));
- servletOutStream.flush();
- } catch (CryptographyException | IOException e) {
+ buildFileResponse(servletResp, (anchorCred.getName() +
DataEncoding.DER.getFileExtension()),
anchorCertInfo.getCertificateType().getContentType(),
+ CertificateUtils.writeCertificate(anchorCert,
DataEncoding.DER));
+ } catch (CryptographyException e) {
// noinspection ConstantConditions
- throw new ToolWebException(String.format(
- "Unable to write Discovery trust anchor certificate
(subj={%s}, serialNum=%s, issuer={%s}) data to HTTP servlet output
stream.", anchorCert
- .getSubjectX500Principal().getName(),
anchorCertInfo.getSerialNumber(),
anchorCert.getIssuerX500Principal().getName()), e);
+ throw new ToolWebException(String.format("Unable to write
Discovery trust anchor certificate (subj={%s}, serialNum=%s, issuer={%s})
data.",
+ anchorCert.getSubjectX500Principal().getName(),
anchorCertInfo.getSerialNumber(),
anchorCert.getIssuerX500Principal().getName()), e);
}
}

=======================================
--- /dcdt-web/src/main/webapp/WEB-INF/views/content/content-admin.jsp Wed
Apr 30 15:10:26 2014 UTC
+++ /dcdt-web/src/main/webapp/WEB-INF/views/content/content-admin.jsp Sun
May 4 20:51:50 2014 UTC
@@ -229,8 +229,35 @@
<tiles:putAttribute name="glyph-classes"
value="glyphicon-edit glyphicon-type-success"/>
<tiles:putAttribute name="content" value="Set Instance
Configuration"/>
</tiles:insertDefinition>
+ <tiles:insertDefinition name="component-glyph-button">
+ <tiles:putAttribute
name="attrs">id="admin-instance-config-creds"
disabled="disabled"</tiles:putAttribute>
+ <tiles:putAttribute name="glyph-classes"
value="glyphicon-download-alt glyphicon-type-link"/>
+ <tiles:putAttribute name="content" value="Download
Instance Credentials"/>
+ </tiles:insertDefinition>
</span>
</div>
+ </div>
+ <div id="dialog-admin-instance-config-rm"
class="dialog-admin-instance-config" title="Remove Instance Configuration">
+ <tiles:insertDefinition name="component-glyph">
+ <tiles:putAttribute name="glyph-classes"
value="glyphicon-trash glyphicon-type-error"/>
+ </tiles:insertDefinition>
+ <p>
+ Are you sure you want to remove the current instance
configuration?
+ </p>
+ <p>
+ <strong>Note</strong>: All generated credentials (private keys
+ certificates), including those of the trust anchor, will be permanently
deleted.
+ </p>
+ </div>
+ <div id="dialog-admin-instance-config-set"
class="dialog-admin-instance-config" title="Re-set Instance Configuration">
+ <tiles:insertDefinition name="component-glyph">
+ <tiles:putAttribute name="glyph-classes" value="glyphicon-edit
glyphicon-type-success"/>
+ </tiles:insertDefinition>
+ <p>
+ Are you sure you want to set the instance configuration again?
+ </p>
+ <p>
+ <strong>Note</strong>: All current generated credentials
(private keys + certificates), including those of the trust anchor, will be
overwritten.
+ </p>
</div>
</form>
<iframe id="admin-instance-config-target" class="hide"
name="admin-instance-config-target" src="about:blank"></iframe>
=======================================
--- /dcdt-web/src/main/webapp/WEB-INF/views/content/head-admin.jsp Wed Apr
30 15:10:26 2014 UTC
+++ /dcdt-web/src/main/webapp/WEB-INF/views/content/head-admin.jsp Sun May
4 20:51:50 2014 UTC
@@ -14,6 +14,7 @@
var URL_ADMIN_INSTANCE_CONFIG_GET = "${urlAdminInstanceConfigGet}";
var URL_ADMIN_INSTANCE_CONFIG_RM = "${urlAdminInstanceConfigRemove}";
var URL_ADMIN_INSTANCE_CONFIG_SET = "${urlAdminInstanceConfigSet}";
+var URL_ADMIN_INSTANCE_CONFIG_CREDS = "${urlAdminInstanceConfigCreds}";
var ADMIN_INSTANCE_CONFIG_DIR_BASE = "${adminInstanceConfigDirBase}";
var URL_ADMIN_SERVICE_HUB_GET = "${urlAdminServiceHubGet}";
</script>
=======================================
--- /dcdt-web/src/main/webapp/WEB-INF/views/include/head.jsp Wed Apr 30
15:10:26 2014 UTC
+++ /dcdt-web/src/main/webapp/WEB-INF/views/include/head.jsp Sun May 4
20:51:50 2014 UTC
@@ -19,6 +19,7 @@
<spring:url var="urlAdminInstanceConfigGet" value="/admin/instance"
scope="request"/>
<spring:url var="urlAdminInstanceConfigRemove" value="/admin/instance/rm"
scope="request"/>
<spring:url var="urlAdminInstanceConfigSet" value="/admin/instance/set"
scope="request"/>
+<spring:url var="urlAdminInstanceConfigCreds"
value="/admin/instance/creds" scope="request"/>
<spring:url var="urlAdminLogin" value="/admin/login" scope="request"/>
<spring:url var="urlAdminLoginProcess" value="/admin/login/process"
scope="request"/>
<spring:url var="urlAdminLogout" value="/admin/logout" scope="request"/>
=======================================
--- /dcdt-web/src/main/webapp/static/scripts/admin.js Wed Apr 30 15:10:26
2014 UTC
+++ /dcdt-web/src/main/webapp/static/scripts/admin.js Sun May 4 20:51:50
2014 UTC
@@ -128,10 +128,12 @@

if (instanceConfigDomainName &&
instanceConfigIpAddr) {
instanceConfigButtonRm.removeAttr("disabled");
+
instanceConfigButtonCreds.removeAttr("disabled");

$.dcdt.admin.getServiceHub("STARTED");
} else {

instanceConfigButtonRm.attr("disabled", "disabled");
+
instanceConfigButtonCreds.attr("disabled", "disabled");

$.dcdt.admin.getServiceHub("STOPPED");
}
@@ -148,7 +150,7 @@
});

var serviceHubForm, serviceInputDnsStatus, serviceInputLdapStatus,
serviceInputMailStatus, serviceHub;
- var instanceConfigForm, instanceConfigInputDomainName,
instanceConfigInputIpAddr, instanceConfigButtons, instanceConfigButtonRm,
instanceConfigButtonSet, instanceConfig;
+ var instanceConfigForm, instanceConfigInputDomainName,
instanceConfigInputIpAddr, instanceConfigButtons, instanceConfigButtonRm,
instanceConfigButtonSet, instanceConfigButtonCreds, instanceConfigDialogRm,
instanceConfigDialogSet, instanceConfig;

$(document).ready(function () {
serviceHubForm = $("form[name=\"admin-service-hub\"]");
@@ -162,18 +164,55 @@
instanceConfigButtons = instanceConfigForm.dcdt.form.formButtons();
instanceConfigButtonRm =
instanceConfigForm.dcdt.form.formButtons("#admin-instance-config-rm");
instanceConfigButtonSet =
instanceConfigForm.dcdt.form.formButtons("#admin-instance-config-set");
+ instanceConfigButtonCreds =
instanceConfigForm.dcdt.form.formButtons("#admin-instance-config-creds");
+ instanceConfigDialogRm = $("div#dialog-admin-instance-config-rm",
instanceConfigForm);
+ instanceConfigDialogSet =
$("div#dialog-admin-instance-config-set", instanceConfigForm);

instanceConfigForm.submit(function (event, instanceConfigButton) {
if (instanceConfigButton.is(instanceConfigButtonRm)) {
- $.dcdt.admin.removeInstanceConfig();
+ instanceConfigDialogRm.dialog({
+ "buttons": {
+ "Remove Instance Configuration": function () {
+ $(this).dialog("close");
+
+ $.dcdt.admin.removeInstanceConfig();
+ },
+ "Cancel": function () {
+ $(this).dialog("close");
+ }
+ },
+ "modal": true
+ });
} else if (instanceConfigButton.is(instanceConfigButtonSet)) {
- instanceConfig = {
- "@type": "instanceConfig",
- "domainName": instanceConfigInputDomainName.val(),
- "ipAddr": instanceConfigInputIpAddr.val()
- };
-
- $.dcdt.admin.setInstanceConfig();
+ if (instanceConfig["domainName"] &&
instanceConfig["ipAddr"]) {
+ instanceConfigDialogSet.dialog({
+ "buttons": {
+ "Re-set Instance Configuration": function () {
+ $(this).dialog("close");
+
+ instanceConfig = {
+ "@type": "instanceConfig",
+ "domainName":
instanceConfigInputDomainName.val(),
+ "ipAddr":
instanceConfigInputIpAddr.val()
+ };
+
+ $.dcdt.admin.setInstanceConfig();
+ },
+ "Cancel": function () {
+ $(this).dialog("close");
+ }
+ },
+ "modal": true
+ });
+ } else {
+ instanceConfig = {
+ "@type": "instanceConfig",
+ "domainName": instanceConfigInputDomainName.val(),
+ "ipAddr": instanceConfigInputIpAddr.val()
+ };
+
+ $.dcdt.admin.setInstanceConfig();
+ }
}
});

@@ -181,6 +220,14 @@
var instanceConfigButton = $(event.target);

if (!instanceConfigButton.attr("disabled")) {
+ if (instanceConfigButton.is(instanceConfigButtonCreds)) {
+ instanceConfigForm.attr("action",
URL_ADMIN_INSTANCE_CONFIG_CREDS);
+ instanceConfigForm.attr("method", "get");
+ } else {
+ instanceConfigForm.attr("action", "about:blank");
+ instanceConfigForm.attr("method", "post");
+ }
+
instanceConfigForm.trigger("submit", [
instanceConfigButton ]);
}
});
=======================================
--- /dcdt-web/src/main/webapp/static/styles/admin.css Fri Dec 6 12:29:39
2013 UTC
+++ /dcdt-web/src/main/webapp/static/styles/admin.css Sun May 4 20:51:50
2014 UTC
@@ -0,0 +1,9 @@
+div.dialog-admin-instance-config {
+ display: none;
+}
+
+div.dialog-admin-instance-config span.glyphicon {
+ display: block;
+ float: left;
+ margin-right: 5px;
+}

==============================================================================
Revision: d11399541551
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 00:25:45 2014 UTC
Log: - Supports DCDT-40.
- Added license file.
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=d11399541551

Added:
/LICENSE

=======================================
--- /dev/null
+++ /LICENSE Mon May 5 00:25:45 2014 UTC
@@ -0,0 +1,23 @@
+Copyright 2014 ESAC, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+The DCDT logo is a derivative work created by the modification and
combination of two source images:
+ 1. The Direct Project logo, used under CC BY 3.0
(http://creativecommons.org/licenses/by/3.0/us/legalcode).
+ For more information see http://directproject.org/.
+ 2. The icon image certificate-server.svg
(http://websvn.kde.org/*checkout*/trunk/kdesupport/oxygen-icons/128x128/places/certificate-server.png)
from the
+ Oxygen Icon set (http://www.oxygen-icons.org/), a copy of which is
made available in the top level of the DCDT source code, and is used under
LGPL
+ (https://www.gnu.org/licenses/lgpl.html).
+
+The DCDT logo is licensed under LGPL by ESAC, Inc.

==============================================================================
Revision: 58717c73d749
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 00:41:11 2014 UTC
Log: - Further supports DCDT-40.
- Modified certificate-server.svg SVN path to point to ZIP file.
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=58717c73d749

Modified:
/LICENSE

=======================================
--- /LICENSE Mon May 5 00:25:45 2014 UTC
+++ /LICENSE Mon May 5 00:41:11 2014 UTC
@@ -16,7 +16,7 @@
The DCDT logo is a derivative work created by the modification and
combination of two source images:
1. The Direct Project logo, used under CC BY 3.0
(http://creativecommons.org/licenses/by/3.0/us/legalcode).
For more information see http://directproject.org/.
- 2. The icon image certificate-server.svg
(http://websvn.kde.org/*checkout*/trunk/kdesupport/oxygen-icons/128x128/places/certificate-server.png)
from the
+ 2. The icon image certificate-server.svg
(http://websvn.kde.org/*checkout*/trunk/kdesupport/oxygen-icons/scalable/places/certificate-server.svgz)
from the
Oxygen Icon set (http://www.oxygen-icons.org/), a copy of which is
made available in the top level of the DCDT source code, and is used under
LGPL
(https://www.gnu.org/licenses/lgpl.html).


==============================================================================
Revision: 16e9aa2fb07d
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 03:47:29 2014 UTC
Log: - Supports DCDT-221.
- Improved handling for empty DNS TCP channel reads.
- Improved DNS service component lifecycle management.
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=16e9aa2fb07d

Modified:

/dcdt-core/src/main/java/gov/hhs/onc/dcdt/nio/channels/impl/AbstractTcpChannelListener.java

/dcdt-service-dns/src/main/java/gov/hhs/onc/dcdt/service/dns/impl/DnsServiceImpl.java

/dcdt-service-dns/src/main/java/gov/hhs/onc/dcdt/service/dns/server/impl/DnsServerChannelListenerSelectorImpl.java

/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/context/impl/DriverManagerServletContextListener.java

/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/service/impl/ToolServiceHubImpl.java

=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/nio/channels/impl/AbstractTcpChannelListener.java
Tue Feb 25 21:16:43 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/nio/channels/impl/AbstractTcpChannelListener.java
Mon May 5 03:47:29 2014 UTC
@@ -48,7 +48,11 @@
readChannel.close();
selKey.cancel();
} else if (!reqBuffer.hasRemaining()) {
- return super.processReadOperation(selKey, readChannel,
selAttachment);
+ if (reqBuffer.position() > 0) {
+ return super.processReadOperation(selKey, readChannel,
selAttachment);
+ } else {
+ selKey.cancel();
+ }
}

selKey.selector().wakeup();
=======================================
---
/dcdt-service-dns/src/main/java/gov/hhs/onc/dcdt/service/dns/impl/DnsServiceImpl.java
Tue Apr 29 00:09:36 2014 UTC
+++
/dcdt-service-dns/src/main/java/gov/hhs/onc/dcdt/service/dns/impl/DnsServiceImpl.java
Mon May 5 03:47:29 2014 UTC
@@ -1,6 +1,7 @@
package gov.hhs.onc.dcdt.service.dns.impl;

import gov.hhs.onc.dcdt.beans.Phase;
+import gov.hhs.onc.dcdt.beans.utils.ToolBeanFactoryUtils;
import gov.hhs.onc.dcdt.context.AutoStartup;
import gov.hhs.onc.dcdt.service.ServiceContextConfiguration;
import gov.hhs.onc.dcdt.service.dns.DnsService;
@@ -10,7 +11,6 @@
import javax.annotation.Nullable;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.stereotype.Component;

@@ -19,11 +19,10 @@
@Phase(Phase.PHASE_PRECEDENCE_HIGHEST)

@ServiceContextConfiguration({ "spring/spring-service-dns.xml", "spring/spring-service-dns-*.xml"
})
public class DnsServiceImpl extends AbstractToolService implements
DnsService {
- @Autowired(required = false)
private List<DnsServer> servers;

@Override
- protected synchronized void stopInternal() throws Exception {
+ protected void stopInternal() throws Exception {
if (this.hasServers()) {
for (DnsServer server : this.servers) {
server.stop();
@@ -32,7 +31,9 @@
}

@Override
- protected synchronized void startInternal() throws Exception {
+ protected void startInternal() throws Exception {
+ this.servers =
ToolBeanFactoryUtils.getBeansOfType(this.appContext, DnsServer.class);
+
if (this.hasServers()) {
for (DnsServer server : this.servers) {
server.start();
=======================================
---
/dcdt-service-dns/src/main/java/gov/hhs/onc/dcdt/service/dns/server/impl/DnsServerChannelListenerSelectorImpl.java
Tue Apr 29 00:09:36 2014 UTC
+++
/dcdt-service-dns/src/main/java/gov/hhs/onc/dcdt/service/dns/server/impl/DnsServerChannelListenerSelectorImpl.java
Mon May 5 03:47:29 2014 UTC
@@ -1,8 +1,8 @@
package gov.hhs.onc.dcdt.service.dns.server.impl;

import gov.hhs.onc.dcdt.beans.Phase;
+import gov.hhs.onc.dcdt.beans.utils.ToolBeanFactoryUtils;
import gov.hhs.onc.dcdt.context.AutoStartup;
-import gov.hhs.onc.dcdt.beans.utils.ToolBeanFactoryUtils;
import gov.hhs.onc.dcdt.nio.channels.impl.AbstractChannelListenerSelector;
import gov.hhs.onc.dcdt.service.dns.config.DnsServerConfig;
import
gov.hhs.onc.dcdt.service.dns.server.DnsServerChannelListenerSelector;
@@ -30,9 +30,11 @@
}

@Override
- public void afterPropertiesSet() throws Exception {
+ protected void startInternal() throws Exception {

this.setChannelListeners(ToolBeanFactoryUtils.createBeanOfType(this.appContext,
DnsServerUdpChannelListener.class, this.dnsServerConfig),
ToolBeanFactoryUtils.createBeanOfType(this.appContext,
DnsServerTcpChannelListener.class, this.dnsServerConfig));
+
+ super.startInternal();
}

@Override
=======================================
---
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/context/impl/DriverManagerServletContextListener.java
Thu Feb 6 11:41:47 2014 UTC
+++
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/context/impl/DriverManagerServletContextListener.java
Mon May 5 03:47:29 2014 UTC
@@ -5,12 +5,10 @@
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.servlet.ServletContextEvent;
-import javax.servlet.annotation.WebListener;
import org.apache.commons.collections4.EnumerationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

-@WebListener("driverManagerServletContextListener")
public class DriverManagerServletContextListener extends
AbstractToolServletContextListener {
private final static Logger LOGGER =
LoggerFactory.getLogger(DriverManagerServletContextListener.class);

=======================================
---
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/service/impl/ToolServiceHubImpl.java
Wed Apr 30 15:10:26 2014 UTC
+++
/dcdt-web/src/main/java/gov/hhs/onc/dcdt/web/service/impl/ToolServiceHubImpl.java
Mon May 5 03:47:29 2014 UTC
@@ -1,6 +1,5 @@
package gov.hhs.onc.dcdt.web.service.impl;

-import gov.hhs.onc.dcdt.beans.Phase;
import gov.hhs.onc.dcdt.beans.impl.AbstractToolLifecycleBean;
import gov.hhs.onc.dcdt.beans.utils.ToolBeanFactoryUtils;
import gov.hhs.onc.dcdt.context.AutoStartup;
@@ -22,7 +21,6 @@

@AutoStartup
@Component("toolServiceHubImpl")
-@Phase(Phase.PHASE_PRECEDENCE_HIGHEST + 3)
public class ToolServiceHubImpl extends AbstractToolLifecycleBean
implements ToolServiceHub {
private final static Logger LOGGER =
LoggerFactory.getLogger(ToolServiceHubImpl.class);

@@ -49,7 +47,7 @@
this.serviceMsgsMap.put(serviceType,
ToolArrayUtils.asList(String.format("Unable to stop service (class=%s,
type=%s, status=%s): %s",
ToolClassUtils.getName(service), serviceType.name(),
service.getLifecycleStatus().name(), e.getMessage())));

- LOGGER.error(String.format("Unable to start service
(class=%s, type=%s, status=%s).", ToolClassUtils.getName(service),
serviceType.name(),
+ LOGGER.error(String.format("Unable to stop service
(class=%s, type=%s, status=%s).", ToolClassUtils.getName(service),
serviceType.name(),
service.getLifecycleStatus().name()), e);
}
}

==============================================================================
Revision: 5fe9e009e7c8
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 05:22:45 2014 UTC
Log: - Further supports DCDT-221.
- Added IPv4 system properties to all forked JVM(s).
- Cleaned-up admin console confirmation dialogs.
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=5fe9e009e7c8

Modified:
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/PemType.java

/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CertificateUtils.java
/dcdt-parent/pom.xml
/dcdt-service-parent/pom.xml
/dcdt-web/pom.xml
/dcdt-web/src/main/webapp/WEB-INF/views/content/content-admin.jsp
/dcdt-web/src/main/webapp/static/scripts/admin.js
/dcdt-web/src/main/webapp/static/styles/admin.css
/dcdt-web/src/main/webapp/static/styles/web.css

=======================================
--- /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/PemType.java Sun May
4 20:51:50 2014 UTC
+++ /dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/PemType.java Mon May
5 05:22:45 2014 UTC
@@ -2,10 +2,10 @@

import java.security.PrivateKey;
import java.security.PublicKey;
-import java.security.cert.X509Certificate;
+import java.security.cert.Certificate;

public enum PemType implements CryptographyTypeIdentifier {
- PUBLIC_KEY("PUBLIC KEY", PublicKey.class), PRIVATE_KEY("PRIVATE KEY",
PrivateKey.class), X509_CERTIFICATE("X.509 CERTIFICATE",
X509Certificate.class);
+ PUBLIC_KEY("PUBLIC KEY", PublicKey.class), PRIVATE_KEY("PRIVATE KEY",
PrivateKey.class), CERTIFICATE("CERTIFICATE", Certificate.class);

private final String id;
private final Class<?> type;
=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CertificateUtils.java
Sun May 4 20:51:50 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/crypto/utils/CertificateUtils.java
Mon May 5 05:22:45 2014 UTC
@@ -82,7 +82,7 @@
try {
byte[] data = cert.getEncoded();

- return ((dataEnc == DataEncoding.DER) ? data :
PemUtils.writePemContent(PemType.X509_CERTIFICATE, data));
+ return ((dataEnc == DataEncoding.DER) ? data :
PemUtils.writePemContent(PemType.CERTIFICATE, data));
} catch (CertificateEncodingException e) {
throw new
gov.hhs.onc.dcdt.crypto.certs.CertificateException(String.format("Unable to
write certificate instance (class=%s) to data.",
ToolClassUtils.getClass(cert)), e);
=======================================
--- /dcdt-parent/pom.xml Sun May 4 20:51:50 2014 UTC
+++ /dcdt-parent/pom.xml Mon May 5 05:22:45 2014 UTC
@@ -1112,6 +1112,7 @@

<dcdt.data.dir>${project.build.directory}/surefire-data</dcdt.data.dir>

<dcdt.log.context.name>${project.artifactId}-test</dcdt.log.context.name>

<dcdt.log.dir>${project.build.directory}/surefire-logs</dcdt.log.dir>
+
<java.net.preferIPv4Addresses>true</java.net.preferIPv4Addresses>

<java.net.preferIPv4Stack>true</java.net.preferIPv4Stack>

<logback.configurationFile>${project.logback.config.file}</logback.configurationFile>
</systemPropertyVariables>
=======================================
--- /dcdt-service-parent/pom.xml Wed Apr 30 19:02:53 2014 UTC
+++ /dcdt-service-parent/pom.xml Mon May 5 05:22:45 2014 UTC
@@ -606,6 +606,7 @@

<extraArgument>-XX:MaxGCPauseMillis=50</extraArgument>

<extraArgument>-XX:ParallelGCThreads=4</extraArgument>

<extraArgument>-XX:ConcGCThreads=4</extraArgument>
+
<extraArgument>-Djava.net.preferIPv4Addresses=true</extraArgument>

<extraArgument>-Djava.net.preferIPv4Stack=true</extraArgument>

<extraArgument>-Djava.security.manager</extraArgument>

<extraArgument>-Djava.security.policy=conf/service/wrapper-service.policy</extraArgument>
=======================================
--- /dcdt-web/pom.xml Sun May 4 20:51:50 2014 UTC
+++ /dcdt-web/pom.xml Mon May 5 05:22:45 2014 UTC
@@ -663,6 +663,8 @@
<systemProperties>

<dcdt.log.context.name>${project.artifactId}-test</dcdt.log.context.name>

<dcdt.log.dir>${project.build.directory}/surefire-logs</dcdt.log.dir>
+
<java.net.preferIPv4Addresses>true</java.net.preferIPv4Addresses>
+
<java.net.preferIPv4Stack>true</java.net.preferIPv4Stack>
</systemProperties>
<webapps>
<webapp>
=======================================
--- /dcdt-web/src/main/webapp/WEB-INF/views/content/content-admin.jsp Sun
May 4 20:51:50 2014 UTC
+++ /dcdt-web/src/main/webapp/WEB-INF/views/content/content-admin.jsp Mon
May 5 05:22:45 2014 UTC
@@ -237,22 +237,22 @@
</span>
</div>
</div>
- <div id="dialog-admin-instance-config-rm"
class="dialog-admin-instance-config" title="Remove Instance Configuration">
- <tiles:insertDefinition name="component-glyph">
- <tiles:putAttribute name="glyph-classes"
value="glyphicon-trash glyphicon-type-error"/>
- </tiles:insertDefinition>
+ <div id="dialog-admin-instance-config-rm" title="Remove Instance
Configuration">
<p>
+ <tiles:insertDefinition name="component-glyph">
+ <tiles:putAttribute name="glyph-classes"
value="glyphicon-trash glyphicon-type-error"/>
+ </tiles:insertDefinition>
Are you sure you want to remove the current instance
configuration?
</p>
<p>
<strong>Note</strong>: All generated credentials (private keys
+ certificates), including those of the trust anchor, will be permanently
deleted.
</p>
</div>
- <div id="dialog-admin-instance-config-set"
class="dialog-admin-instance-config" title="Re-set Instance Configuration">
- <tiles:insertDefinition name="component-glyph">
- <tiles:putAttribute name="glyph-classes" value="glyphicon-edit
glyphicon-type-success"/>
- </tiles:insertDefinition>
+ <div id="dialog-admin-instance-config-set" title="Re-set Instance
Configuration">
<p>
+ <tiles:insertDefinition name="component-glyph">
+ <tiles:putAttribute name="glyph-classes"
value="glyphicon-edit glyphicon-type-success"/>
+ </tiles:insertDefinition>
Are you sure you want to set the instance configuration again?
</p>
<p>
=======================================
--- /dcdt-web/src/main/webapp/static/scripts/admin.js Sun May 4 20:51:50
2014 UTC
+++ /dcdt-web/src/main/webapp/static/scripts/admin.js Mon May 5 05:22:45
2014 UTC
@@ -168,42 +168,48 @@
instanceConfigDialogRm = $("div#dialog-admin-instance-config-rm",
instanceConfigForm);
instanceConfigDialogSet =
$("div#dialog-admin-instance-config-set", instanceConfigForm);

+ instanceConfigDialogRm.dialog({
+ "autoOpen": false,
+ "buttons": {
+ "Remove Instance Configuration": function () {
+ instanceConfigDialogRm.dialog("close");
+
+ $.dcdt.admin.removeInstanceConfig();
+ },
+ "Cancel": function () {
+ instanceConfigDialogRm.dialog("close");
+ }
+ },
+ "modal": true
+ });
+
+ instanceConfigDialogSet.dialog({
+ "autoOpen": false,
+ "buttons": {
+ "Re-set Instance Configuration": function () {
+ instanceConfigDialogSet.dialog("close");
+
+ instanceConfig = {
+ "@type": "instanceConfig",
+ "domainName": instanceConfigInputDomainName.val(),
+ "ipAddr": instanceConfigInputIpAddr.val()
+ };
+
+ $.dcdt.admin.setInstanceConfig();
+ },
+ "Cancel": function () {
+ instanceConfigDialogSet.dialog("close");
+ }
+ },
+ "modal": true
+ });
+
instanceConfigForm.submit(function (event, instanceConfigButton) {
if (instanceConfigButton.is(instanceConfigButtonRm)) {
- instanceConfigDialogRm.dialog({
- "buttons": {
- "Remove Instance Configuration": function () {
- $(this).dialog("close");
-
- $.dcdt.admin.removeInstanceConfig();
- },
- "Cancel": function () {
- $(this).dialog("close");
- }
- },
- "modal": true
- });
+ instanceConfigDialogRm.dialog("open");
} else if (instanceConfigButton.is(instanceConfigButtonSet)) {
if (instanceConfig["domainName"] &&
instanceConfig["ipAddr"]) {
- instanceConfigDialogSet.dialog({
- "buttons": {
- "Re-set Instance Configuration": function () {
- $(this).dialog("close");
-
- instanceConfig = {
- "@type": "instanceConfig",
- "domainName":
instanceConfigInputDomainName.val(),
- "ipAddr":
instanceConfigInputIpAddr.val()
- };
-
- $.dcdt.admin.setInstanceConfig();
- },
- "Cancel": function () {
- $(this).dialog("close");
- }
- },
- "modal": true
- });
+ instanceConfigDialogSet.dialog("open");
} else {
instanceConfig = {
"@type": "instanceConfig",
=======================================
--- /dcdt-web/src/main/webapp/static/styles/admin.css Sun May 4 20:51:50
2014 UTC
+++ /dcdt-web/src/main/webapp/static/styles/admin.css Mon May 5 05:22:45
2014 UTC
@@ -1,9 +0,0 @@
-div.dialog-admin-instance-config {
- display: none;
-}
-
-div.dialog-admin-instance-config span.glyphicon {
- display: block;
- float: left;
- margin-right: 5px;
-}
=======================================
--- /dcdt-web/src/main/webapp/static/styles/web.css Wed Apr 30 15:10:26
2014 UTC
+++ /dcdt-web/src/main/webapp/static/styles/web.css Mon May 5 05:22:45
2014 UTC
@@ -247,6 +247,20 @@
div.input-group-sm div.form-group.form-group-buttons
span.btn-group.btn-group-sm button.btn {
font-size: 13px;
}
+
+div.ui-widget.ui-dialog {
+ display: none;
+ font-size: 11px;
+}
+
+div.ui-widget.ui-dialog span.glyphicon {
+ float: left;
+ margin-right: 6px;
+}
+
+div.ui-widget.ui-dialog p {
+ display: inline-block;
+}

div#footer {
height: 60px;

==============================================================================
Revision: 9aa91aa9e4a3
Branch: default
Author: Michal Kotelba <michal....@esacinc.com>
Date: Mon May 5 07:15:57 2014 UTC
Log: - Further supports DCDT-220.
- Merged message digest processing fixes.
- Improved mail service remote delivery responsiveness.
http://code.google.com/p/direct-certificate-discovery-tool/source/detail?r=9aa91aa9e4a3

Added:
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/impl/LineOutputStream.java
Modified:

/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtils.java
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/utils/ToolMimePartUtils.java

/dcdt-service-mail/src/main/resources/META-INF/spring/spring-service-mail.xml

=======================================
--- /dev/null
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/impl/LineOutputStream.java
Mon May 5 07:15:57 2014 UTC
@@ -0,0 +1,54 @@
+package gov.hhs.onc.dcdt.mail.impl;
+
+import gov.hhs.onc.dcdt.utils.ToolClassUtils;
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import javax.mail.MessagingException;
+
+/**
+ * @see org.bouncycastle.mail.smime.SMIMEUtil
+ */
+public class LineOutputStream extends FilterOutputStream {
+ private static byte[] newLine;
+
+ static {
+ newLine = new byte[2];
+ newLine[0] = (byte) ('\r');
+ newLine[1] = (byte) ('\n');
+ }
+
+ public LineOutputStream(OutputStream outputStream) {
+ super(outputStream);
+ }
+
+ public void writeln(String str) throws MessagingException {
+ try {
+ byte[] byteArr = getBytes(str);
+ super.out.write(byteArr);
+ this.writeln();
+ } catch (Exception e) {
+ throw new MessagingException(String.format("Unable to write
line to output stream (%s):", ToolClassUtils.getName(out)), e);
+ }
+ }
+
+ public void writeln() throws MessagingException {
+ try {
+ super.out.write(newLine);
+ } catch (Exception e) {
+ throw new MessagingException(String.format("Unable to write
line to output stream (%s):", ToolClassUtils.getName(out)), e);
+ }
+ }
+
+ private static byte[] getBytes(String s) {
+ char[] charArr = s.toCharArray();
+ int i = charArr.length;
+ byte[] byteArr = new byte[i];
+ int j = 0;
+
+ while (j < i) {
+ byteArr[j] = (byte) charArr[j++];
+ }
+
+ return byteArr;
+ }
+}
=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtils.java
Sun May 4 20:51:50 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/crypto/utils/ToolSmimeUtils.java
Mon May 5 07:15:57 2014 UTC
@@ -7,15 +7,22 @@
import gov.hhs.onc.dcdt.crypto.credentials.CredentialInfo;
import gov.hhs.onc.dcdt.crypto.utils.CertificateUtils;
import gov.hhs.onc.dcdt.crypto.utils.CryptographyUtils;
+import gov.hhs.onc.dcdt.mail.impl.LineOutputStream;
import gov.hhs.onc.dcdt.mail.MailContentTransferEncoding;
import gov.hhs.onc.dcdt.mail.MailContentTypes;
+import gov.hhs.onc.dcdt.mail.crypto.MailDigestAlgorithm;
import gov.hhs.onc.dcdt.mail.crypto.MailEncryptionAlgorithm;
import gov.hhs.onc.dcdt.mail.crypto.ToolSmimeException;
import gov.hhs.onc.dcdt.mail.impl.ToolMimeMessageHelper;
import gov.hhs.onc.dcdt.mail.utils.ToolMimePartUtils;
import gov.hhs.onc.dcdt.utils.ToolClassUtils;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
@@ -23,6 +30,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
+import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -32,19 +40,25 @@
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.security.auth.x500.X500Principal;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.asn1.cms.CMSAttributes;
import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;
import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSSignerDigestMismatchException;
import org.bouncycastle.cms.KeyTransRecipientId;
import org.bouncycastle.cms.KeyTransRecipientInformation;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformation;
+import org.bouncycastle.cms.SignerInformationVerifier;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
@@ -58,6 +72,7 @@
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
import org.bouncycastle.mail.smime.SMIMEUtil;
import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Store;
import org.springframework.util.MimeType;

@@ -80,34 +95,37 @@
JcaSimpleSignerInfoVerifierBuilder signerInfoVerifierBuilder = new
JcaSimpleSignerInfoVerifierBuilder();
Map<SignerId, SignerInformation> signerInfoMap =
mapSigners(signed);
Map<SignerId, CertificateInfo> signerCertMap = new
LinkedHashMap<>(signerInfoMap.size());
- SignerInformation signerInfo;
+ SignerInformation signerInfo = null;

for (SignerId signerId : signerInfoMap.keySet()) {
- signerInfo = signerInfoMap.get(signerId);
-
for (X509CertificateHolder certHolder :
((Collection<X509CertificateHolder>) signedCerts.getMatches(signerId))) {
try {
- signerCertMap.put(signerId, new
CertificateInfoImpl(CertificateUtils.CERT_CONV.getCertificate(certHolder)));
- } catch (CertificateException e) {
- throw new ToolSmimeException(String.format("Unable to
verify mail signed data signer (id={issuer=%s, serialNum=%s}).",
- signerId.getIssuer(), new
CertificateSerialNumberImpl(signerId.getSerialNumber())), e);
- }
+ try {
+ SignerInformationVerifier verifier =
signerInfoVerifierBuilder.build(certHolder);
+ signerInfo = signerInfoMap.get(signerId);

- // @formatter:off
- /*
- try {
- if
(signerInfo.verify(signerInfoVerifierBuilder.build(certHolder))) {
- signerCertMap.put(signerId, new
CertificateInfoImpl(CertificateUtils.CERT_CONV.getCertificate(certHolder)));
+ if (signerInfo.verify(verifier)) {
+ signerCertMap.put(signerId, new
CertificateInfoImpl(CertificateUtils.CERT_CONV.getCertificate(certHolder)));
+ }
+ } catch (CMSSignerDigestMismatchException e) {
+ byte[] calculatedDigest = getMessageDigest(signed,
signerInfo, signerId, certHolder);
+ // noinspection ConstantConditions
+ byte[] expectedDigest =
+
ASN1OctetString.getInstance(signerInfo.getSignedAttributes().get(CMSAttributes.messageDigest).getAttrValues().getObjectAt(0))
+ .getOctets();

- break;
+ if (!Arrays.constantTimeAreEqual(expectedDigest,
calculatedDigest)) {
+ throw new
ToolSmimeException(String.format("Expected message digest value: %s does
not match the calculated message digest: %s",
+ Hex.encodeHexString(expectedDigest),
Hex.encodeHexString(calculatedDigest)), e);
+ } else {
+ signerCertMap.put(signerId, new
CertificateInfoImpl(CertificateUtils.CERT_CONV.getCertificate(certHolder)));
+ }
}
} catch (CertificateException | CMSException |
OperatorCreationException e) {
throw new ToolSmimeException(String.format(
"Unable to verify mail signed data signer
(id={issuer=%s, serialNum=%s}) certificate (subj={%s}).",
signerId.getIssuer(),
new
CertificateSerialNumberImpl(signerId.getSerialNumber()),
certHolder.getSubject()), e);
}
- */
- // @formatter:on
}

if (!signerCertMap.containsKey(signerId)) {
@@ -118,6 +136,42 @@

return signerCertMap;
}
+
+ @SuppressWarnings({ "unchecked" })
+ public static byte[] getMessageDigest(SMIMESigned signed,
SignerInformation signerInfo, SignerId signerId, X509CertificateHolder
certHolder)
+ throws ToolSmimeException {
+ try (ByteArrayOutputStream byteArrayOutStream = new
ByteArrayOutputStream(); LineOutputStream lineOutStream = new
LineOutputStream(byteArrayOutStream)) {
+ MimeBodyPart mp = signed.getContent();
+ Enumeration<String> headers = mp.getAllHeaderLines();
+
+ while (headers.hasMoreElements()) {
+ String header = headers.nextElement();
+ header = header.substring(0,
header.indexOf(ToolMimePartUtils.DELIM_HEADER) + 1) +
header.substring(header.indexOf(StringUtils.SPACE) + 1);
+ lineOutStream.writeln(header);
+ }
+
+ lineOutStream.writeln();
+
+ try (BufferedReader reader = new BufferedReader(new
InputStreamReader(mp.getInputStream()))) {
+ String line;
+
+ while ((line = reader.readLine()) != null) {
+ lineOutStream.writeln(line);
+ }
+ }
+
+ byteArrayOutStream.flush();
+
+ // noinspection ConstantConditions
+ return MessageDigest.getInstance(
+ CryptographyUtils.findObjectId(MailDigestAlgorithm.class,
new ASN1ObjectIdentifier(signerInfo.getDigestAlgOID())).getId()).digest(
+ byteArrayOutStream.toByteArray());
+ } catch (NoSuchAlgorithmException | IOException |
MessagingException e) {
+ throw new ToolSmimeException(String.format(
+ "Unable to calculate message digest for MIME message with
signer (id={issuer=%s, serialNum=%s}) certificate (subj={%s}).",
+ signerId.getIssuer(), new
CertificateSerialNumberImpl(signerId.getSerialNumber()),
certHolder.getSubject()), e);
+ }
+ }

@SuppressWarnings({ "unchecked" })
public static Map<SignerId, SignerInformation> mapSigners(SMIMESigned
signed) throws MessagingException {
=======================================
---
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/utils/ToolMimePartUtils.java
Thu Apr 3 21:05:25 2014 UTC
+++
/dcdt-core/src/main/java/gov/hhs/onc/dcdt/mail/utils/ToolMimePartUtils.java
Mon May 5 07:15:57 2014 UTC
@@ -22,6 +22,8 @@
import org.springframework.util.MimeTypeUtils;

public abstract class ToolMimePartUtils {
+ public final static String DELIM_HEADER = ":";
+
public static Map<String, MimeBodyPart>
mapAttachmentPartFileNames(MimeMultipart multipart) throws
MessagingException {
int numBodyParts = multipart.getCount();
Map<String, MimeBodyPart> attachmentPartFileNameMap = new
LinkedHashMap<>(numBodyParts);
=======================================
---
/dcdt-service-mail/src/main/resources/META-INF/spring/spring-service-mail.xml
Sun May 4 20:51:50 2014 UTC
+++
/dcdt-service-mail/src/main/resources/META-INF/spring/spring-service-mail.xml
Mon May 5 07:15:57 2014 UTC
@@ -276,8 +276,11 @@
p:className="RemoteDelivery">
<beans:property
name="initParameters">
<util:map>
+ <beans:entry
key="connectiontimeout" value="#{
T(gov.hhs.onc.dcdt.utils.ToolDateUtils).MS_IN_SEC * 15 }"/>
+ <beans:entry
key="delayTime" value="1 minute"/>
<beans:entry
key="deliveryThreads" value="20"/>
- <beans:entry
key="maxRetries" value="0"/>
+ <beans:entry
key="maxRetries" value="5"/>
+ <beans:entry key="timeout"
value="#{ T(gov.hhs.onc.dcdt.utils.ToolDateUtils).MS_IN_SEC * 30 }"/>
</util:map>
</beans:property>
</beans:bean>
Reply all
Reply to author
Forward
0 new messages