Thanks Garry for your reply, and I am sorry for the slowness of my
response, I been busy doing internet research trying to grok everything
you said in your suggestions. I think the best thing to do is to walk
you and other readers through the steps I took to create the LetsEncrypt
certificate and put it in the keystore. Then I will comment on each of
your suggestions and await for further clarification on what I should
try/do next.  I am not at all familiar with the code and inner workings
of Apache James so to me a lot of this is like trying to understand
what  is in a room by looking through a keyhole! LOL

OK, these are the steps I took -

To create the LetsEncrypt certificate I used the DNS challenge method to
create a wildcard certificate for all the domains and subdomains that I
provide email services for. This was done as follows using the certbot
command -

certbot certonly  --config-dir /etc/letsencrypt_forApacheJames
--dns-rfc2136 --dns-rfc2136-credentials
/etc/letsencrypt_forApacheJames/james/rfc2136.ini
--dns-rfc2136-propagation-seconds 10 --server
https://acme-v02.api.letsencrypt.org/directory
--preferred-challenges=dns --email postmas...@domainname.com --agree-tos
-d domainname1.com -d *.domainname1.com  -d domainname2.com -d
*.domainname2.com   /etc.../

If I understand things correctly this produced 4 certificate and chain
files -

cert.pem is the certificate containing the public key for my domains.
chain.pem is the certificate for my certificate authority - LetsEncrypt
fullchain.pem is also created by certbot = cert.pem + chain.pem
privkey.pem containing the private key for my domains.

Next I created an empty keystore in the conf directory for Apache James -

cd /mail/apache-james-3.4/james-server-app-3.4.0/conf
mkdir keystore.privateFiles
cd keystore.privateFiles
keytool -genkeypair -keyalg RSA -alias emptykeystore -keystore keystore.jks

and I  migrated the keystore to PKCS12 format and deleted the
emptykeystore alias using

keytool -importkeystore -srckeystore keystore.jks -destkeystore
keystore.jks -deststoretype pkcs12
keytool -delete -alias emptykeystore -keystore keystore.jks

Next I converted the keys created by certbot into the proper format for
importing it into the keystore, using openssl to convert the keys -

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out
pkcs.p12 -name james

This creates a file called pkcs.p12 which I then import into the
keystore file -

keytool -importkeystore -deststorepass mypassword -destkeypass
mypassword -destkeystore keystore.jks -srckeystore
/etc/letsencrypt_forApacheJames/live/mydomain.com-0001/pkcs.p12
-srcstoretype PKCS12 -srcstorepass mypassword -alias james

I left out a few details like sensitive info, cd'ing to various
different directories and setting up a link to the keystore file. The
passwords are simple alphanumeric character strings. I will intersperse
the rest of my reply in-between your comments -

On 1/3/20 2:12 PM, Garry Hurley wrote:
> Okay. One thing I noticed before. The key took command will hash the password 
> with the appropriate algorithm and use it to access the keystone file. James 
> code is not guaranteed to use the appropriate hashing algorithm. Try the 
> following:
I am not sure what you mean and are referring to as the hashing
algorithm though I do know what hashing is. In the steps I showed you,
that I took to create the keystore, I see parameters that specify
encryption algorithms but nothing that specifies a hashing algorithm.
> 1 sift through the code, find the hashing algorithm used by James and hard 
> code the hashed key in the configuration file. 
Oh boy, I am not set up to build James from source and suspect that will
be a steep learning curve. I will table this option for the moment and
consider it if option 2 doesn't work.
> 2, find out which hashing algorithm is used to encrypt the key and specify it 
> in the configuration file
This sounds promising except I don't know what hashing algorithm was
used in creating the keys. I suspect you are referring to the encryption
algorithm? (I know nothing about how the encryption is actually done,
but could imagine that it is based on a hash of some kind. I believe
that I am using the RSA encryption algorithm but check me on that... 
Also I don't know how to specify the "hashing algorithm" in the
configuration files so an example would be very helpful.
> 3, create a new key store WITHOUT a password and use that one instead. 
This sounds dangerous and I will try this approach also if all else
fails... But yeah it sounds like another path I could follow...
> For ease of use, #3 is the clear winner. For maximum security, #1 would be 
> preferred.   I am almost certain you will find it is due to a hashing 
> algorithm or, alternatively, a character in the password that is expressly 
> probibited in an XML file (like an ampersand or greater/less than sign for 
> example). 
The password is only composed of lower case letters and numbers. No
punctuation characters are used.

I don't know if this is applicable but in my internet searches looking
for discussions about the same or similar error messages that I am
seeing, I am seeing some references to problems with the tools from
BouncyCastle.  Here are a couple of links, perhaps you or some other
guru could check these out and see if I am perhaps experiencing the same
or similar issue as these folks are talking about -

https://stackoverflow.com/questions/53542198/adding-bouncycastle-provider-breaks-keystore-load

https://github.com/bcgit/bc-java/issues/586

This is above my pay grade to understand so again many thanks and I
appreciate yours and any other help offered...    Marc...

>
> Sent from my iPhone
>
>> On Dec 28, 2019, at 9:35 PM, Marc Chamberlin 
>> <m...@marcchamberlin.com.invalid> wrote:
>>
>> Hello again,  It appears that I have managed to make a bit of progress
>> on my own since my original post. For some odd reason I got past the
>> FileNotFound exception by changing (adding) execute permission to the
>> directory containing the keystore file. So now it is set as follows -
>>
>> quasar:/mail/apache-james-3.4/james-server-app-3.4.0/conf # ll -d
>> keystore.privateFiles
>> drwxrwxrwx 2 james mail 4096 Dec 27 22:11 keystore.privateFiles
>>
>> It is a puzzler (at least to me) why adding execute permissions would
>> allow James to find my Keystore file. But I immediately hit another
>> snag, James is not correctly applying the password to access the
>> keystore file and throwing another exception. The smtpserver.xml is
>> configured as follows -
>>
>>      <tls socketTLS="false" startTLS="true">
>>       
>> <keystore>file:/mail/apache-james-3.4/james-server-app-3.4.0/conf/keystore</keystore>
>>        <secret>mypassword</secret>
>>       
>> <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>>        <algorithm>SunX509</algorithm>
>>      </tls>
>>
>> To test the keystore file I executed the following command and it worked
>> fine -
>>
>> quasar:/mail/apache-james-3.4/james-server-app-3.4.0/conf # keytool
>> -list -v -keystore
>> /mail/apache-james-3.4/james-server-app-3.4.0/conf/keystore -storetype
>> PKCS12 -storepass mypassword
>>
>> The exception and stack walkback I am getting from James is shown
>> below.  I am continuing to Google for answers but no joy so far...
>> Anyone here got any ideas? Thanks again in advance...     Marc.
>>
>> ----
>>
>> INFO   | jvm 1    | 2019/12/28 17:13:27 | WARN  17:13:26,963 |
>> org.apache.james.container.spring.context.JamesServerApplicationContext
>> | Exception encountered during context initialization - cancelling
>> refresh attempt:
>> org.springframework.beans.factory.BeanCreationException: Error creating
>> bean with name 'smtpserver': Invocation of init method failed; nested
>> exception is java.io.IOException: keystore password was incorrect
>> INFO   | jvm 1    | 2019/12/28 17:13:27 | INFO  17:13:26,964 |
>> org.apache.james.mailetcontainer.impl.JamesMailSpooler | start dispose() ...
>> INFO   | jvm 1    | 2019/12/28 17:13:27 | INFO  17:13:26,964 |
>> org.apache.james.mailetcontainer.impl.JamesMailSpooler | thread shutdown
>> completed.
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |
>> INFO   | jvm 1    | 2019/12/28 17:13:27 | WrapperSimpleApp: Encountered
>> an error running main:
>> org.springframework.beans.factory.BeanCreationException: Error creating
>> bean with name 'smtpserver': Invocation of init method failed; nested
>> exception is java.io.IOException: keystore password was incorrect
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |
>> org.springframework.beans.factory.BeanCreationException: Error creating
>> bean with name 'smtpserver': Invocation of init method failed; nested
>> exception is java.io.IOException: keystore password was incorrect
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:396)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1507)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:638)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.apache.james.container.spring.context.JamesServerApplicationContext.<init>(JamesServerApplicationContext.java:40)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.apache.james.app.spring.JamesAppSpringMain.init(JamesAppSpringMain.java:56)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.apache.james.app.spring.JamesAppSpringMain.main(JamesAppSpringMain.java:42)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> java.lang.reflect.Method.invoke(Method.java:498)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> java.lang.Thread.run(Thread.java:748)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 | Caused by:
>> java.io.IOException: keystore password was incorrect
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2059)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:238)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> java.security.KeyStore.load(KeyStore.java:1445)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer.buildSSLContext(AbstractConfigurableAsyncServer.java:405)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer.init(AbstractConfigurableAsyncServer.java:263)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.apache.james.protocols.lib.netty.AbstractServerFactory.init(AbstractServerFactory.java:57)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> java.lang.reflect.Method.invoke(Method.java:498)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:344)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:295)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       at
>> org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130)
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       ... 22 more
>> INFO   | jvm 1    | 2019/12/28 17:13:27 | Caused by:
>> java.security.UnrecoverableKeyException: failed to decrypt safe contents
>> entry: java.lang.IllegalStateException: password has been cleared
>> INFO   | jvm 1    | 2019/12/28 17:13:27 |       ... 36 more
>>
>> -- 
>>
>>  --...  ...--  .----.  ...    -..  .    .--  .-  --...  .--.  -..-  .--     
>> --  .-  .-.  -.-. 
>>
>>
>> *Computers: the final frontier. These are the voyages of the user Marc.
>> His mission: to explore strange new hardware. To seek out new software
>> and new applications.
>> To boldly go where no Marc has gone before!
>> *
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: server-user-unsubscr...@james.apache.org
> For additional commands, e-mail: server-user-h...@james.apache.org
>

-- 

  --...  ...--  .----.  ...    -..  .    .--  .-  --...  .--.  -..-  .--     -- 
 .-  .-.  -.-. 


*Computers: the final frontier. These are the voyages of the user Marc.
His mission: to explore strange new hardware. To seek out new software
and new applications.
To boldly go where no Marc has gone before!
*

Reply via email to