bbottema/simple-java-mail

bug on Email.signWithDomainKey(File, String, String)

WinstonHKLee opened this issue · 2 comments

Email.signWithDomainKey(File, String, String) new FileInputStream(File) and finally close(). ( too good coding habbit! )
This make the class member Email.dkimPrivateKeyInputStream unusable.
Later MimeMessageHelper.signMessageWithDKIM(MimeMessage, Email) new DkimSigner, the closed FileInputStream throws DataFetchException:

org.simplejavamail.mailer.internal.mailsender.MailSenderException: Error signing MimeMessage with DKIM
        at org.simplejavamail.mailer.internal.mailsender.MimeMessageHelper.signMessageWithDKIM(MimeMessageHelper.java:269) ~[simple-java-mail-4.1.1.jar:na]
        at org.simplejavamail.mailer.internal.mailsender.MimeMessageHelper.produceMimeMessage(MimeMessageHelper.java:82) ~[simple-java-mail-4.1.1.jar:na]
        at org.simplejavamail.mailer.internal.mailsender.MailSender.sendMailClosure(MailSender.java:219) ~[bin/:na]
        at org.simplejavamail.mailer.internal.mailsender.MailSender.send(MailSender.java:200) ~[bin/:na]
        at org.simplejavamail.mailer.Mailer.sendMail(Mailer.java:400) ~[bin/:na]
        at org.simplejavamail.mailer.Mailer.sendMail(Mailer.java:391) ~[bin/:na]
        at [...]
Caused by: net.markenwerk.utils.data.fetcher.DataFetchException: Fetch failed after 0 bytes have been copied successully.
        at net.markenwerk.utils.data.fetcher.AbstractBufferedDataFetcher.createException(AbstractBufferedDataFetcher.java:98) ~[bin/:na]
        at net.markenwerk.utils.data.fetcher.AbstractBufferedDataFetcher.doCopy(AbstractBufferedDataFetcher.java:90) ~[bin/:na]
        at net.markenwerk.utils.data.fetcher.AbstractDataFetcher.doCopy(AbstractDataFetcher.java:112) ~[bin/:na]
        at net.markenwerk.utils.data.fetcher.AbstractDataFetcher.copy(AbstractDataFetcher.java:106) ~[bin/:na]
        at net.markenwerk.utils.data.fetcher.AbstractDataFetcher.fetch(AbstractDataFetcher.java:73) ~[bin/:na]
        at net.markenwerk.utils.data.fetcher.AbstractDataFetcher.fetch(AbstractDataFetcher.java:61) ~[bin/:na]
        at net.markenwerk.utils.mail.dkim.DkimSigner.<init>(DkimSigner.java:220) ~[bin/:na]
        at org.simplejavamail.mailer.internal.mailsender.MimeMessageHelper.signMessageWithDKIM(MimeMessageHelper.java:260) ~[simple-java-mail-4.1.1.jar:na]
        ... 8 common frames omitted
Caused by: java.io.IOException: Stream Closed
        at java.io.FileInputStream.readBytes(Native Method) ~[na:1.8.0_91]
        at java.io.FileInputStream.read(FileInputStream.java:233) ~[na:1.8.0_91]
        at net.markenwerk.utils.data.fetcher.AbstractBufferedDataFetcher.doCopy(AbstractBufferedDataFetcher.java:79) ~[bin/:na]
        ... 14 common frames omitted

To fix, and taken I/O expense into account, I suggest to cache the byte[] into static Map<File,byte[]> inside Email.signWithDomainKey(File, String, String): (any security consideration on storing private key?)

class Email {
   static Map<File,byte[]> cachedDomainKeys = new HashMap<>();

public void signWithDomainKey(final File dkimPrivateKeyFile, final String signingDomain, final String selector) {
    [...]
    byte[] bytes = org.apache.commons.io.FileUtils.readFileToByteArray(dkimPrivateKeyFile);
    cachedDomainKeys.put(dkimPrivateKeyFile, bytes);
    dkimPrivateKeyInputStream = new ByteArrayInputStream(bytes);
    [...]

Thanks.

Haha, yeah that's not going to work, thanks for reporting. I'll think of something this weekend probably. Meanwhile you can use the overloaded version with FileInputStream instead.

Released in v4.1.2