tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daniel" <dpury...@verizon.net>
Subject Re: KeyStore question
Date Sun, 23 Oct 2005 17:46:50 GMT
All,

This is as far as I have gotten.  As I said, I believe I still have some 
issues with the certificates because I

believe Tomcat is suppose to populate the HttpRequest object with a series 
of "attributes" that we should be able to

use to retrieve things like the X.509 certificates.  I found one site that 
said we should be able to simply issue

something like:
 X509Certificate cert = 
request.getAttribute("java.security.cert.X509Certificate");

in order to get the specifics of the user.  As configured per the notes 
below, the SSL session "appears" to be OK as

the servlet gets dispatched as anticipated; only the HttpRequest object's 
atrribute array is EMPTY, the principal is

null, but secure = = true.

If anyone out there in CertificateLand or the Tomcat realm can tell us 
what's missing, this list ( not the least of

whom is yours truely) could sure use the help!!  I think We have the simple 
stuff (Form Login) under control, we

need deep down help on SSL, Certificates, and MutalAuthetication.

********* Mutal Authetication Progress notes follow *********

Since the list doesn't handle enclosures, and I don't have a fixed IP 
address server to FTP from, here's a lengthy

series of snaps and notes:

Here's a batch file that will create a Certificate Authority in the /ca 
directory that you can use to sign any

number of certs:

rem file: CreateCA.bat
openssl req -config ca.cnf -extensions ca_ext -new -newkey 
rsa:1024 -nodes -out ca/ca.csr -keyout ca/ca.key
pause
openssl x509 -trustout -signkey ca/ca.key -days 3650 -req -in ca/ca.csr -out 
ca/ca.pem
echo
echo "STOP!  1) Copy ca.pem -> ca.crt; 2)Edit ca.crt "TRUSTED 
CERTIFICATE" -> "CERTIFICATE""
echo "Then continue"
pause


Here's a batch file that will create, then sign, then package in a p12 
format Client certificate for a browser

import:

rem file: CreateClient.bat
echo "When prompted for common name, provide the users common name, e.g. 
"Daniel Puryear"
pause
openssl req -config ca.cnf -extensions user_ext -new -newkey 
rsa:1024 -nodes -out client/client1.req -keyout

client/client1.key
pause
openssl x509 -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/ca.ser -req -in 
client/client1.req -out client/client1.pem

-days 3650
pause
openssl pkcs12 -export -clcerts -in client/client1.pem -inkey 
client/client1.key -out client/client1.p12 -name

"Tomcat_Test_CERT"
pause

Here's a batch file that will create, then sign a server certificate, then 
package in a keystore called

"server.keystore"

rem file: CreateServer.bat
echo "You can provide data interactively if you remove the -dname parameter"
pause
keytool -genkey -alias tomcat -keyalg RSA -keysize 1024 -keystore 
server/server.keystore -storetype JKS -dname

"CN=localhost, OU=NSIT, O=NGC, L=Columbia, S=MD, C=US" -keypass 
changeit -storepass changeit
pause
keytool -certreq -keyalg RSA -alias tomcat -file server/server.csr -keystore 
server/server.keystore  -keypass

changeit -storepass changeit
echo
echo "STOP! Edit server.csr from 'NEW CERTIFICATE REQUEST' -> 'CERTIFICATE 
REQUEST' "
echo "Then continue.  When prompted for a EXPORT password, use 'changeit' 
also..."
pause
openssl x509 -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/ca.ser -req -in 
server/server.csr -out server/server.crt

-days 3650
pause
rem HEADS_UP! SEQUENCE ORDER DEPENDENCY!!  CA first, so the tomcat import 
can find the CA when needed!!
keytool -import -alias rootCA -keystore 
server/server.keystore -trustcacerts -file ca/ca.pem -keypass changeit

-storepass changeit
pause
keytool -import -alias tomcat -keystore 
server/server.keystore -trustcacerts -file server/server.crt -keypass

changeit -storepass changeit
pause


Here's a batch (crude) to create a truststore to contain your CA's public 
key and save it in a file called

trust.keystore

rem file: CreateTrustStore.bat
keytool -genkey -alias truststore -keyalg RSA -keysize 1024 -keystore 
trust/trust.keystore -storetype JKS -dname

"CN=truststore, OU=NSIT, O=NGC, L=Columbia, S=MD, C=US" -keypass 
changeit -storepass changeit
pause
rem
rem Cause the TC signed CERT to be trusted by loading into the trusted 
keystore(Public key Only )
keytool -import -alias rootCA -keystore 
trust/trust.keystore -trustcacerts -file ca/ca.pem -keypass changeit

-storepass changeit
pause



You can find several places on the web that basically contains the above, 
but here's an OpenSSL config file that

picks up the details.  If you don't want the challenge/response dialog ( 
which, by the way, only the Foxfire engine gets right!  Netscape, the 
inventers of SSL, no longer handles the SSL itself, it delegates to you 
option of either the Foxfire or MSIE SSL engine), comment out entries in the 
req_attributes section.


#
# SSLeay example configuration file as modified by D Puryear.
#

RANDFILE  = .rnd

####################################################################
[ ca ]
default_ca = CA_default  # The default ca section

####################################################################
[ CA_default ]

dir  = .   # Where everything is kept
certs  = $dir\certs  # Where the issued certs are kept
crl_dir  = $dir\crl  # Where the issued crl are kept
database = $dir\index.txt # database index file.
new_certs_dir = $dir\newcerts  # default place for new certs.

certificate = $dir\cacert.pem     # The CA certificate
serial  = $dir\serial      # The current serial number
crl  = $dir\crl.pem      # The current CRL
private_key = $dir\private\cakey.pem   # The private key
RANDFILE = $dir\private\private.rnd # private random number file

# Over-riding to force the use of a "-extensions xyz" on each "req" command
#x509_extensions = x509v3_extensions # The extentions to add to the cert

default_days = 3650   # how long to certify for
default_crl_days= 365   # how long before next CRL
default_md = SHA1   # which md to use.
preserve = no   # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy  = policy_match

# For the CA policy
[ policy_match ]
countryName  = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName  = supplied
emailAddress  = optional


####################################################################
[ req ]
default_bits  = 1024
default_keyfile  = privkey.pem
distinguished_name = req_distinguished_name
attributes  = req_attributes
input_password  = changeit
output_password  = changeit

[ req_distinguished_name ]
countryName   = Country Name (2 letter code)
countryName_default  = US
countryName_min   = 2
countryName_max   = 2

stateOrProvinceName  = State or Province Name (full name)
stateOrProvinceName_default = MD
localityName   = Locality Name (eg, city)
localityName_default  = Columbia
organizationName  = Organization Name (eg, company)
organizationName_default = NGC
organizationalUnitName  = Organizational Unit Name (eg, section)
organizationalUnitName_default = NSIT
commonName   = Common Name (eg, your website's domain name)
commonName_default  = <Enter Real Common Name>
commonName_max   = 64

[ req_attributes ]
challengePassword  = A challenge password
challengePassword_default = changeit
challengePassword_min  = 4
challengePassword_max  = 20



#
#Invoke for CA certs only
[ ca_ext ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always
basicConstraints = critical, CA:true, pathlen:2
keyUsage = critical, digitalSignature, keyCertSign, cRLSign

[user_ext]
basicConstraints = critical, CA:false
keyUsage = critical, digitalSignature, keyEncipherment
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid

[server_cert]
basicConstraints = critical, CA:false
keyUsage = critical, digitalSignature, keyEncipherment
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid

##******End of File *******




OpenSSL instructions.
1) Download the Windows binary executable from the OpenSSl site and unpack.
2) CD into the bin dir and create ca, client, server, and trust directories.
3) In the ca directory, creat a text file called "ca.ser".  In it, add two 
characters '0', and '1'
   Its the serial number counter that the CA will use for stamping the certs 
it signs.
4) Copy the OpenSSL configuration above into a file called "ca.cnf" and 
place it in the OpenSSL bin directory
5) Likewise, create the four batch files and place them in the bin 
directory.
6) Execute the CreateCA, CreateClient, CreateServer, CreateTrustStore batch 
files in that order.


Tomcat instructions:
1) Track down the Tomcat version your using to find out where it likes to 
see the server cert.
In 5.5.12, it likes TOMCAT_HOME (so do I), 5.5.9 requires it in the user's 
home dictory of the user account that

launches Tomcat.  Copy the server.keystore to that directory.

2) Copy the trust.keystore to the TOMCAT_HOME.  Remember why we're doing 
this. Without an explicitly assigned trust

store, Tomcat will go to the prevailing JDK/JRE and load the contents of 
/lib/cacerts as the only "trusted" signers.
We short-circuit that pathing to specify our trust store until we are 
satisfied we have it right. Afterwards, we

could load out "rootCA" trusted CA into the JRE's cacerts if you want.

3) Modify Tomcats server.xml file to add/modify the SSL connector to provide 
the correct pathign to the two stores.

I used:
        <Connector port="8443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="true" sslProtocol="TLS"
               keystoreFile="server.keystore" keystorePass="changeit" 
keystoreType="JKS"
               truststoreFile="trust.keystore" truststorePass="changeit" 
truststoreType="JKS"
        />

4) Add the certificate's CommonName for each client to the tomcat-users.xml 
file.  My play version is:
 <?xml version='1.0' encoding='utf-8'?>
 <tomcat-users>
    <role rolename="user"/>
    <role rolename="tomcat"/>
    <role rolename="role1"/>
    <role rolename="manager"/>
    <role rolename="admin"/>
    <user username="Daniel Puryear danielp" password="" 
roles="admin,manager,tomcat,user"/>
    <user username="tomcat" password="tomcat" roles="tomcat"/>
    <user username="both" password="tomcat" roles="tomcat,role1"/>
    <user username="role1" password="tomcat" roles="role1"/>
    <user username="admin" password="admin" roles="admin,manager"/>
 </tomcat-users>

At this point Tomcat should find a client match and complete the SSL 
"session" setup (not the HTTP session)

5) If you want Tomcat to provide user role control on a servlet by servlet 
basis, edit the WebApps web.xml file. My

play version is:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" >
 <display-name>
 HelloWebProj</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
 </welcome-file-list>

 <servlet>
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>HelloWorld</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
 <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <security-constraint>
      <display-name>Example Security Constraint</display-name>
      <web-resource-collection>
         <web-resource-name>Protected H Area</web-resource-name>
  <!-- Define the context-relative URL(s) to be protected -->
         <url-pattern>/h/*</url-pattern>
  <!-- If you list http methods, only those methods are protected -->
      <http-method>DELETE</http-method>
             <http-method>GET</http-method>
             <http-method>POST</http-method>
      <http-method>PUT</http-method>
         </web-resource-collection>
      <auth-constraint>
         <!-- Anyone with one of the listed roles may access this area -->
         <role-name>tomcat</role-name>
      </auth-constraint>
    </security-constraint>
 <login-config>
           <auth-method>CLIENT-CERT</auth-method>
           <realm-name>tomcat-users</realm-name>
    </login-config>
    <!-- Security roles referenced by this web application -->
    <security-role>
      <role-name>tomcat</role-name>
    </security-role>
</web-app>

If you need to watch/debug the SSL protocol handshaking include 
the -Djavax.net.debug=all System property.  I used a

batch file to launch Tomcat while I was debugging the certificate issues:

java -Dcatalina.home="C:\Program Files\Apache Software Foundation\Tomcat 
5.5" -Djava.endorsed.dirs="C:\Program

Files\Apache Software Foundation\Tomcat 
5.5\common\endorsed" -Djavax.net.debug=all -cp ./bin/bootstrap.jar

org.apache.catalina.startup.Bootstrap "start"
pause




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message