Tuesday Jun 22, 2010

Metro support for JAAS Keystore Login Module

KeyStoreLoginModule: This class provides a JAAS login module that prompts for a key store alias and populates the subject with the alias's principal and credentials. Stores an X500Principal for the subject distinguished name of the first certificate in the alias's credentials in the subject's principals, the alias's certificate path in the subject's public credentials, and a X500PrivateCredential whose certificate is the first certificate in the alias's certificate path and whose private key is the alias's private key in the subject's private credentials.


For more details , go through the link JAASKeyStoreLoginModule .The clear usage of this keystore login module is documented here 


This feature is just an  another way of configuring keystore's properties in the wsdl configuration.With this support in metro,  we can configure the PKCS#11 keystore types also


To use this feature with metro,  follow the below steps:


1) Configure a jaas keystore login module entry in the Glassfish's login.conf file($GF_Home/domains/domain1/config/login.conf) as shown below

JAASLoginModuleForKeyStore{
    com.sun.security.auth.module.KeyStoreLoginModule required
    keyStoreURL="file:///home/suresh/glassfish/domains/domain1/config/keystore.jks"
    keyStoreType="JKS"
    keyStoreAlias="xws-security-client"
    keyStorePasswordURL="file:///home/suresh/glassfish/domains/domain1/config/JAASKeystorePassword.txt";
};

If you are providing a callback handler for this login module ,  in the wsdl configuration,you don't need to configure the keyStoreAlias and keyStorePasswordURL in the config entry.


Otherwise


If you are using a stand alone web service/client , we have to set a property like this :


-Djava.security.auth.login.config=mycustompath/login.conf where this login.conf file contains a login module entry as stated above


2) The existing way of configuring the keystore properties in wsdl looks like :


<sc:KeyStore wspp:visibility="private" location="/home/suresh/glassfish/domains/domain1/config/keystore.jks" type="JKS" storepass="changeit" alias="xws-security-server"/>


with this keystore login module feature , we can simply configure the keystore as :


<sc:KeyStore wspp:visibility="private" keystoreloginmoduleconfig="JAASLoginModuleForKeyStore" />


or in addition, if we want to provide a  custom callback handler for login module which looks like :


<sc:KeyStore wspp:visibility="private" keystoreloginmoduleconfig="JAASLoginModuleForKeyStore" callbackHandler="suresh.test.KeyStoreCallbackHandler"/>


where the JAASLoginModuleForKeyStore is the glassfish login module config entry as shown above . Metro reads the keystoreloginmoduleconfig entry from the keystore and uses it to access the GF's config entry and thus populates the subject with certificate and privatekeys.Metro gets the certificate/privatekeys from this subject and uses them for signature/encryption.


The advantage of this feature is we can configure the PKCS#11 keystore types in addition to the default .JKS types


Note:


1) This login module feature works only for keystore's , but not for truststores .


2) If you are using a callback handler for login module , then the login module expects the TextOutputCallback, NameCallback( for specifying cert alias), PasswordCallback(for keystore password), and ConfirmationCallback(for login confirmation) in the callback handler


The sample callback handler is attached here


The sample  netbeans webservice client(build/web/WEB-INF/classes/META-INF/NewWebServiceService.xml) which uses the above feature is attached here


Download the latest metro nightly builds from here










Wednesday Mar 10, 2010

Support of RSA-SHA256, RSA-SHA384 and RSA-SHA512 Algorithms in Metro

The existing metro versions support only RSA-SHA1 or HMAC-SHA1 algorithms for computing signatures when securing  the messages.To be more precise , in the request/response messages , you can see something like:


............................
<ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
           <exc14n:InclusiveNamespaces PrefixList="wsse S"/>
        </ds:CanonicalizationMethod>
       <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
    <ds:Reference URI="#_5002">


.............................


As the usage of RSA-SHA1  is discouraged according to the XML working draft (go to section 6.1)   for signatures, recently we started working on providing the support of RSA-SHA256 ,RSA-SHA384, RSA-SHA512 algorithm for signatures.


From 10th Mar 2010 Nightly build , the support of above algorithms is available and users can specify the algorithm that they want to use for signatures  with a extra configuration steps.


For example, if you want to use RSA-SHA512 as signature algorithm , you have to configure one extra custom attribute in the AlgorithmSuite as follows:


                       <sp:AlgorithmSuite signatureAlgorithm="SHA512withRSA">
                                 <wsp:Policy>
                                     <sp:Basic128/>
                                 </wsp:Policy>
                        </sp:AlgorithmSuite>


also for RSA-SHA256:


                              <sp:AlgorithmSuite signatureAlgorithm="SHA256withRSA">

                                 <wsp:Policy>

                                     <sp:Basic128/>

                                 </wsp:Policy>

                        </sp:AlgorithmSuite>


You can check the algorithm used for signature request/response  messages. For ex:you should see something similar to the below snippet , depending on your algorithm configuration:


............................
<ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
           <exc14n:InclusiveNamespaces PrefixList="wsse S"/>
        </ds:CanonicalizationMethod>
       <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha512"/>
 <ds:Reference URI="#_5002">


.............................


Please note that the default signature algorithm used is "rsa-sha1" , so if you don't specify any algorithm attribute in the AlgorithmSuite , it will take only "rsa-sha1"



Please use the latest nightly builds  , if you want to use the above feature


Download Link:


https://metro.dev.java.net/servlets/ProjectDocumentList?folderID=11914&expandFolder=11914&folderID=10314

Tuesday Nov 03, 2009

Securing Web Applications with Servlet Security:Part-1

The purpose of this blog is to give a brief idea, to the readers, about securing web applications with servlet security.

 According to Servlet Spec 3.0 , the servlet security is divided into 4 concepts,

                                                                      i) Authentication

                                                                     ii) Authorization

                                                                    iii) Confidentiality

                                                                    iv) Data Integrity(or Data Privacy)

1)Authentication: This is the process of verification about the client that he /she is actually the person who he/she is claiming .They are 4 types of authentication mechanisms which are

i) HTTP Basic Authentication:The basic credentials to authenticate an user is by his/her username and password. The user should produce his/her
username and password to authenticate themselves to access a web service resource.

How it works? when the user requests for a restricted resource , the server find that it is a restricted resource and so requests for authentication(username and password).When the user sends his username/password , server checks the credentials given by user against a secure database called realm.After conforming , the sever sends back the response . for ex: the Tomcat 6.0.18 's realm( user's database) is in conf/tomcat-users.xml file and looks like  

                                <tomcat-users>

                                                  <user username="tomcat" password="tomcat" roles="guest"/>

                                                  <user username="suresh" password="mandalapu" roles="member,guest"/>

                                                  <user username="Sun" password="xwss" roles="manager"/>

                                </tomcat-users>

The adavantage of this authentication is it is easy to implement and all browsers support it, but the disadvantage is it is not secure because the username/password are not encrypted

ii) HTTP Digest Authentication:The  Digest authentication is the same as Basic except that in this case, the password is sent in an encrypted format. This makes it more secure.

How it works? same as basic authnetication

The disadvatage of this authentication is that it is not supported by many servlet containers since the specification does not mandate it.It is not supported by many browsers also.

iii) HTTPS Client  cert authentication: HTTPS is HTTP plus secure socket layer.In this method the authentication is performed when the SSL connection is established between the browser and the server. All the data is transmitted in the encrypted form using public-key cryptography, which is handled by the browser and the servlet container

How it works? first ssl is configured between client and server. and the must must have a certificate produced by organizations such as Verizon

iv) FORM based authentication: This is same as basic authentication

How it works? Instead of browser's pop up box , the developers should write an html form to capture username and password . the form action should be j_security_check and the username and password names should be j_username and j_password.

The disadvantage of this method is it not secure, since the username/password are not encrypted

How to implement the above authentication mechanisms?

To implement any of above 4 mechanisms we have to configure then authentication type the Deployment Descriptor (web.xml) of the web application using the <login-config> tag as shown below

                           <web-app>

                               ..........

                              <login-config>

                                    <auth-method>BASIC</auth-method>

                                    <realm-name>suresh-realm</realm-name>

                               </login-config  

                               ...........

                           <web-app>

           The 4 possiable values are BASIC,DIGEST,CLIENT-CERT,FORM

If it is form based authentication then we do not need to specify the realm name

                 <login-config>

                      <auth-method>FORM</auth-method>

                      <!--realm-name not required for FORM based authentication -->

                      <form-login-config>

                            <form-login-page>/formlogin.html</form-login-page>

                            <form-error-page>/formerror.html</form-error-page>

                      </form-login-config>

                  </login-config>

For detailed discussion on how container implements FORM based auth. see se. 13.6.3 of the spec 3.0.These are the 4 authentication mechanisms that servlet 3.0 spec. follows.. 

2) Authorization: Authorization is the process of determining whether the user is permitted to certain resouces that he/she has requested.For ex: for accesing our bank account we need to authenticate ourselves(authentication), but we are not allowed to access some other's account details(we are not Authorised)

Authorization is just maintaing access control!!

The implementation of  authorization will be discussed in part-2

3) Confidentiality: is nothing but ensuring that  the information is accessed by only intended receipents.This looks similar  to authorization but the difference between them is that authorization prevents the information from reaching(accessing) unintended parties , while confidentiality ensures that even if the information falls into the wrong hands, it cannot be usuable for them.

4) Data Integrity: this gives guartantee that the information or data has not been changed by somebody while it is in the transmission between client and server. Data integrity is usually ensured by sending a hashcode or signature of the data along with the data. At the receiving end, the data and its hashcode

are verified.If the data and its hash code are same on the other side also, then we can conform that integrity is maintained ,if they are not the same then some body in between the network might have changed the data so the server has to reject the request.

How to implement Confidentiality and Data Integrity? we have to write <transport-guarantee> tag in the DD(web.xml) as shown below 

                                        <security-constraint>

                                              -----------

                                             <user-data-constraint>

                                                    <transport-guarantee>CONFIDENTIAL</transport-guarantee>

                                             </user-data-constraint>

                                       </security-constraint>

The legal values are NONE,CONFIDENTIAL,INTEGRAL

                       NONE------> this is default value which means there is no data protection

                       CONFIDENTIAL----->the data must not be seen bt anybody in the transmission

                       INTEGRAL------>the data must not be changed along the transport

we will see the implementation of servlet security  and securing web applications declaratively and programmetically in part-2

Securing Web Applications with Servlet Security:Part-2

In the part-1 of this blog we have the seen the security mechanisms supported by servlet specification 3.0.

Now we will see how to implement those mechanisms declaratively and programmetically,the two common approaches to security.

Declarative Security:means specifing the security requirements in DD(web.xml) of the web application .The requirements include roles, access control, and authentication requirements(see servlet spec 3.0).

By default web resources(servlets, jsps, etc) are accessable to everybody,so to restrict the resources from public access we need to know about 3 things.

i)Web resource collection:tells which resources are to be protected from public access .

            for ex:   <web-resource-collection>
                             <web-resource-name>reports</web-resource-name>

                              <url-pattern>/servlet/SalesReportServlet/\*</url-pattern>

                              <url-pattern>/servlet/FinanceReportServlet/\*</url-pattern>

                              <url-pattern>/servlet/HRReportServlet/\*</url-pattern>

                              <http-method>GET</http-method>

                              <http-method>POST</http-method>

                         </web-resource-collection>

The <web-resource-name> is optional and is used to easily identify the security constraint.

                 The <url-pattern> is the resource url which we want to protect.

The <http-method> tells that for which type of requests we have to protect the resources.In the above ex.only GET and POST are   specified .So these two are only constrained , but remaining request types(PUT,TRACE, etc) are not constrained.Thus anybody can access  the above resources freely with out any constraint for the remaining request types(PUT,TRACE, etc).

                 If  no <http-method> is specified ,then the constraint is for all types of requests.

ii) Auth Constraint:tells the roles who can only access the specified web resources

                                    for ex:      <auth-constraint>

                                                                <description>accessible to all supervisors and directors</description>

                                                                <role-name>supervisor</role-name>

                                                                <role-name>director</role-name>

                                                     </auth-constraint>

The <description> tag is optional and it describes about the rolls that access the resources

The <role-name> tag tell that the roles which can only access the resources with specified http requests

                      The <role-name>\*</role-name> tag tells that it includes all the roles defined in the web app are constarined.

                      The absence of  <auth-constraint> indicates that it includes all the roles defined in the web app.

                      The empty tag  <auth-constraint/> indicates that nobody can access the specified resources

iii) User -Data-Constraint:which we have seen in the part-1 of the blog.This helps attackers prevent stealing data while it in the transmission. This process involves the use of SSL to encrypt the traffic between the browser and the server.


The complete sample  web.xml can be

<?xml version="1.1" encoding="ISO-8859-1"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

     <servlet>

          <servlet-name>SecureServlet</servlet-name>

          <servlet-class>com.sur.secure.SecureServlet</servlet-class>

     </servlet>

     <servlet-mapping>

          <servlet-name>SecureServlet</servlet-name>

          <url-pattern>/securelogin</url-pattern>

      </servlet-mapping>     

    <security-constraint>

          <web-resource-collection>

              <web-resource-name>wholesale</web-resource-name>

              <url-pattern>/securelogin</url-pattern>

              <http-method>GET</http-method>

              <http-method>POST</http-method>

         </web-resource-collection>

         <auth-constraint>

              <role-name>Manager</role-name>

         </auth-constraint>

        <user-data-constraint>

             <transport-guarantee>CONFIDENTIAL</transport-guarantee>

        </user-data-constraint>

    </security-constraint>

    <security-constraint>

        <web-resource-collection>

             <web-resource-name>retail</web-resource-name>

                   <url-pattern>/someotherservlet</url-pattern>

                   <http-method>GET</http-method>

                   <http-method>POST</http-method>

            </web-resource-collection>

            <auth-constraint>

                   <role-name>Developer</role-name>

             </auth-constraint>

    </security-constraint>

    <login-config>

       <auth-method>FORM</auth-method>

       <form-login-config>

            <form-login-page>/formlogin.html</form-login-page>

             <form-error-page>/formerror.html</form-error-page>

       </form-login-config>

    </login-config>

    <security-role>

      <role-name>Manager</role-name>

      <role-name>Developer</role-name>

    </security-role>

</web-app>

Thus restricting the webresources from public access and allowing only certain roles to access some resources  using declarative security mechanism

With declarative security none of  webresources(servlets/jsps) need to know  security related code

Please note that these protections apply only to direct client access,these does'nt apply to resources which are accessed by means of RequestDispatcher, jsp:forward or jsp:include.

Programmetic Security: With programmatic security, protected servlets and JSP pages at least partially manage their own security. To prevent unauthorized access, each servlet or JSP page must either authenticate the user or verify that the user has been authenticated previously. Even after the servlet or JSP page grants access to a user, it can still customize the results for different individual users or categories of users.

for example, if we want a  servlet to be  accessed by all employees and generate some output for managers and a different output for directors etc,then programmetic security helps here for generating outputs depending on the users roles .

In this mechanism servlet spec. supports 3 methods of HttpServletRequest interface:

1) isUserInRole(): This  method determines if the currently authenticated user belongs to a specified role.If so, this method returns true other wise false.

2) getRemoteUser(): This method returns the login name of the current authenticated user,returns nulll if the user is not authenticated.

3) getUserPrincipal(): This method returns a java.security.Principal   object containing the name of the current authenticated    user. It returns null if the user is not authenticated. Calling the getName() method on the Principal returned by getUserPrincipal
returns the name of the remote user.If the user is not authenticated  getUserPrincipal() method returns null.

                     The reason for using this method is ....

The following sample demonstarates the usages of above methods :

public void doPost(HttpServletRequest req,
                   HttpServletResponse res)
                   throws IOException
   {   PrintWriter pw = res.getWriter();
        pw.println("<html><head>");
        pw.println("<title>Programatic Security Example</title>");
        pw.println("</head>");
        pw.println("<body>");
       String username = req.getRemoteUser();
------------------------->>gets the username
       if(username != null)
          pw.println("<h4>Welcome, "+username+"!</h4>");
       if(req.isUserInRole("director"))------------------->>
determines if the user is a manager
       {  pw.println("<b>Director's Page!</b>");
       } else {
          pw.println("<b>Employee's Page!</b>");
       }
      pw.println("</body></html>");
}





My Blog about Java fundamentals

this is my unofficial blog telling about java fundamentals..


http://sureshjavablog.blogspot.com/


hope you learn something from it..

Wednesday Aug 26, 2009

Support of Endpoint References with Addressing Identity Information in Metro

A Web service endpoint is a (referenceable) entity, processor, or resource where Web service messages can be targeted. WS-Addressing’s Endpoint references convey the information needed to reference a Web service endpoint, and may be used in several different ways: endpoint references are suitable for conveying the information needed to access a Web service endpoint, but are also used to provide addresses for individual messages sent to and from Web services.

Web Services Addressing Identity extends WS-Addressing’s endpoint reference by providing identity information about the endpoint that can be verified through a variety of security means. These means include transport security technologies like https or the wealth of WS-Security specifications.

<wsa:EndpointReference>

       ...........

      <wsid:Identity>

              .......

     </wsid:Identity>

</wsa:EndpointReference>

The identity value can be anything like KeyInfo,X509 Certificate,or any security token like BinarySecurityToken....etc, and it represents the certificate/publickey of the web service

for ex:

</wsa:EndpointReference>

       <wsid:Identity>

          <wsse:BinarySecurityToken ValueType="...#X509v3">

                <!--base64 encoded value of the X509 certificate-->

         </wsse:BinarySecurityToken>

       </wsid:Identity>

<wsa:EndpointReference>

In metro we added this feature recently and it publishes a binary security token as the value of identity element.There are many ways to configure the web service certificate.

The current implementation handles most of the ways to implement this ,here are the ways which are handled.

1) To parse the keystore assertion present  in the service wsdl and get the b.s.token by using the keystore's location , password and alias.Generally the keystore assertion will look like

<sc:KeyStore wspp:visibility="private" location="/home/suresh/glassfish/domains/domain1/config/keystore.jks" type="JKS" storepass="changeit" alias="xws-security-server"/>

2) You can configure Keystore Callback handler  without using location of the keystore or you can use aliasSelector also in place of alias.The current implementation handles all these cases to produce the BST in the Identity Element.

3) Put the X509certificate directly in the file WEB-INF/classes/META-INF/ServerCertificate.cert for servlet based webservices(or in META-INF/ServerCertificate.cert in case of EJB  webservices) and create the BST from it.The file name should be ServerCertificate.cert and metro searches for the file with this name.The contents of the certificate should be in the .DER or .PEM format.

Currently we are using these methods to get the b.s.token ,but in future we would support the full scope of server certificate configuration.

By default this feature is not enabled and If we want to enable this feature we should use the assertion

<sc:EnableEPRIdentity wspp:visibility="private" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"/> in the service wsdl then  metro will add the BST as the identity value to the EPR by using one of the above methods.

Thus clients can use this BST to encrypt the messages,and hence need not specify the peer alias,but the truststore configuration assertion is still needed to validate the certificate.

Please note that if there is no truststore assertion configured on the client side , metro don't accept the certificate and generates a warning that the certificate is not valid.

Currently we are forcing clients to use this feature by default ,but in future we allow them to disable this on their side by using some assertion as above and can use their own configuration.

Sample server side policy which uses the above feature is as shown below:  

<wsp:Policy wsu:Id="NewWebServicePortBindingPolicy">
        <wsp:ExactlyOne>
            <wsp:All>
                <wsam:Addressing wsp:Optional="false"/>
                <sp:AsymmetricBinding>
                    <wsp:Policy>
                        <sp:InitiatorToken>
                            <wsp:Policy>
                                <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                    <wsp:Policy>
                                        <sp:WssX509V3Token10/>
                                        <sp:RequireIssuerSerialReference/>
                                    </wsp:Policy>
                                </sp:X509Token>
                            </wsp:Policy>
                        </sp:InitiatorToken>
                        <sp:RecipientToken>
                            <wsp:Policy>
                                <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                                    <wsp:Policy>
                                        <sp:WssX509V3Token10/>
                                        <sp:RequireIssuerSerialReference/>
                                    </wsp:Policy>
                                </sp:X509Token>
                            </wsp:Policy>
                        </sp:RecipientToken>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Strict/>
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp/>
                        <sp:OnlySignEntireHeadersAndBody/>
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic128/>
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                    </wsp:Policy>
                  </sp:AsymmetricBinding>

<sc:EnableEPRIdentity wspp:visibility="private"xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"/>

                <sp:Wss10>
                    <wsp:Policy>
                        <sp:MustSupportRefIssuerSerial/>
                    </wsp:Policy>
                </sp:Wss10>

          <sc:KeyStore wspp:visibility="private" location="/home/suresh/glassfish/domains/domain1/config/keystore.jks" type="JKS"  storepass="changeit" alias="xws-security-server"/>

               <sp:EndorsingSupportingTokens>
                    <wsp:Policy>
                        <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                                    <wsp:Policy>
                                        <sp:WssX509V3Token10/>
                                        <sp:RequireIssuerSerialReference/>
                                    </wsp:Policy>
                                </sp:X509Token>
                    </wsp:Policy>
                </sp:EndorsingSupportingTokens>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>

After publishing the endpoint reference with a BST as the value of identity , it looks like

<service name="NewWebServiceService">
     <port name="NewWebServicePort" binding="tns:NewWebServicePortBinding">
     <soap:address location="http://localhost:8080/issue1217/NewWebServiceService"/>
     <wsa:EndpointReference>
          <wsa:Address>
                  http://localhost:8080/issue1217/NewWebServiceService
          </wsa:Address>
          <ns10:Identity>                                                   
                 <ns5:BinarySecurityToken ns4:Id="uuid_326775ca-8125-4869-8ff2-b9918f9f22c4"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-  1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
MIIDDzCCAnigAwIBAgIBAjANBgkqhkiG9w0BAQQFADBOMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEMMAoGA1UECh

MDU1VOMQwwCgYDVQQLEwNKV1MxDjAMBgNVBAMTBVNVTkNBMB4XDTA3MDMxMjEwMTgwNVoXDTE3MDMwOTEwMTgwNVowbzELMA

kGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UECxMDU1

VOMRowGAYDVQQDExF4d3NzZWN1cml0eXNlcnZlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAv11fD4vbn2E+RpKgPkDFYzorrGsGq

pdsmsZ3wGewLhSdrDI18Lugs6QcUUTq8dQ17xAWPITQWi0EzXpUhdFTQAi4eiLJnV2SVirz4iyCqbZCzn0gCJxFcJ//+BYwIuWdTLrfya14+47g

KBhFnNSZxmpjZlahf6105AZMTgt05BMCAwEAAaOB2zCB2DAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZC

BDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUdVE29ysyFW/iD1la3ddePzM6IWowfgYDVR0jBHcwdYAUZ7plxs6VyOOOTSFyojDV0YYjJWhUqRQME

4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMQwwCgYDVQQKEwNTVU4xDDAKBgNVBAsTA0pXUzEOMAwGA1UEAxMFU1VOQ

0GCCQDbHkJaq6KijjANBgkqhkiG9w0BAQQFAAOBgQBWpPzVlkGUGarWc0ghob52gvWWjYoQ/2b1zHqUcLGt1fGKcwS0m23PMCWjwcTv4AKz4Z

AtymK9xe9UOoMkJt+N9SuOajGzKvpf7eXaC5d+CcGmIhRDL+8Exz9DVqLDi8MVHd8oMg/WeP2c0q0TCDxXmATn6n9hC0abODh8cLUh7Q==
</ns5:BinarySecurityToken>
           </ns10:Identity>
     </wsa:EndpointReference>
   </port>
</service>

Wednesday Jun 24, 2009

Support of Binding Assertions at the Operation Level in Metro

In the WS-SecurityPolicy 1.0  spec. the Binding assertions were only allowed on the Endpoint Scope.

But according to the latest  1.3 spec it says the Asymmetric and Symmetric Binding  assertions  MAY also appear on the operation scope.

In earlier releases of Metro   there was a bug which prevented it from specifying the policy  on the operation scope . 

For example  if our policy contains 

<binding name="NewWebServicePortBinding" type="tns:NewWebService">  

<wsp:PolicyReference URI="#NewWebServicePortBindingPolicy"/>
        <operation name="ping">           
            <input>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_ping_Input_Policy"/>
            </input>
            <output>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_ping_Output_Policy"/>
            </output>
        </operation>      
</binding>

In the above policy snippet the tag <wsp:PolicyReference URI="#NewWebServicePortBindingPolicy"/> denotes the binding policy which is at the binding level.This policy applies to all operations

Thus all operations in the binding level are secured and if we want to add security to only some of the operations ,it is not possible .

And if we move that policy  to operation level as shown below

<binding name="NewWebServicePortBinding" type="tns:NewWebService">    
        <operation name="ping">    

<wsp:PolicyReference URI="#NewWebServicePortBindingPolicy"/>
            <input>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_ping_Input_Policy"/>
            </input>
            <output>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_ping_Output_Policy"/>
            </output>
        </operation>      
</binding>

then metro throws null pointer exception:

Policy is NULL

javax.xml.ws.soap.SOAPFaultException: ERROR: Policy for the service could not be obtained
    at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:189)
    at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:130)
    at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)

    ............................
Caused by: javax.xml.ws.soap.SOAPFaultException: ERROR: Policy for the service could not be obtained
    at com.sun.xml.ws.security.opt.impl.util.SOAPUtil.createSOAPFault(SOAPUtil.java:202)
    at com.sun.xml.ws.security.opt.impl.util.SOAPUtil.getSOAPFaultException(SOAPUtil.java:194)
    ..................

Caused by: com.sun.xml.wss.impl.PolicyViolationException: ERROR: Policy for the service could not be obtained
    at com.sun.xml.wss.impl.policy.verifier.MessagePolicyVerifier.verifyPolicy(MessagePolicyVerifier.java:112)
    at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.createMessage(SecurityRecipient.java:973)
    at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.validateMessage(SecurityRecipient.java:230)
    at com.sun.xml.wss.provider.wsit.WSITServerAuthContext.verifyInboundMessage(WSITServerAuthContext.java:533)
    at com.sun.xml.wss.provider.wsit.WSITServerAuthContext.validateRequest(WSITServerAuthContext.java:318)
    ... 43 more

...................

Now we are currently working on this and made the necessary  changes in Metro to support the binding assertions at the operation level.

With this change we can secure the operations which we want unlike the previous requirement that all operations  in binding level  will be secured.

So if the policy is such that:

<binding name="NewWebServicePortBinding" type="tns:NewWebService">

        <operation name="Add">
<wsp:PolicyReference URI="#NewWebServicePortBindingPolicy"/>
            <input>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_Add_Input_Policy"/>
            </input>
            <output>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_Add_Output_Policy"/>
            </output>
        </operation>
        <operation name="Subtract">
            <input>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_Subtract_Input_Policy"/>
            </input>
            <output>
                <wsp:PolicyReference URI="#NewWebServicePortBinding_Subtract_Output_Policy"/>
            </output>
        </operation>
    </binding>

the Add operation uses secured messages and the Subtract  will use non secure  plain messages


Wednesday May 27, 2009

SAML token as Initiator Token in Asymmetric Binding with ProtectTokens

The ProtectTokens feature in the current metro version has not been implemented fully and currently we are working on this feature .A bug(wsit:issue 206) related to SAML assertions and ProtectTokens has already been filed on this.

This blog is about how we have fixed the above mentioned bug.

In the Asymmetric binding case,when we use SAML token as an InitiatiorToken with ProtectTokens enabled, the SAML token which we are using for performing Signature should also be signed .

So metro generates some STRID for SAML token to be signed ,but the major problem here is that the SAML assertion ID is not available until the callback handler is invoked.Thus the signature reference would have a non existent id which will cause an exception at runtime like :

javax.xml.ws.WebServiceException: Could not find Reference #ff63e9e3-248d-4f77-8802-5326d58da1a9 under Signature with ID1
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.handleSignature(SecurityRecipient.java:842)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.processSecurityHeader(SecurityRecipient.java:745)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.createMessage(SecurityRecipient.java:526)
at com.sun.xml.ws.security.opt.impl.incoming.SecurityRecipient.validateMessage(SecurityRecipient.java:193)
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.verifyInboundMessage(SecurityPipeBase.java:455)
at com.sun.xml.wss.jaxws.impl.SecurityServerPipe.process(SecurityServerPipe.java:177)
...................
...................
...................

So when using SAML token as Initiator token with ProtectTokens feature , in the saml callback handler  set the assertion id of the assertion on to the saml  callback handler as shown below (assume we are using saml hok type)

public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i=0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof SAMLCallback) {
                try{
                    SAMLCallback samlCallback = (SAMLCallback)callbacks[i];
                    if (samlCallback.getConfirmationMethod().equals(samlCallback.SV_ASSERTION_TYPE)){
                            samlCallback.setAssertionElement(createSVSAMLAssertion());
                            //samlCallback.setAssertionElement(createSVSAMLAssertion20());
                            svAssertion=samlCallback.getAssertionElement();
                    }else if (samlCallback.getConfirmationMethod().equals(samlCallback.HOK_ASSERTION_TYPE)){
                            samlCallback.setAssertionElement(createHOKSAMLAssertion());
                            //samlCallback.setAssertionElement(createHOKSAMLAssertion20());
                            hokAssertion=samlCallback.getAssertionElement();
                       samlCallback.setAssertionId(samlId);

                    }else{
                            throw new Exception("SAML Assertion Type is not matched.");
                    }
                }catch(Exception ex){
                        ex.printStackTrace();
                }
            } else {
                throw unsupported;
            }
        }
    }

Metro would then pick up the assertion id from the saml callback and modify the signature reference to refer to the saml assertion, thus overcoming the missing reference problem.

You can try the same with latest metro builds 

A full SAML Callback Handler can be found here

test samples can be found here

SAMLServer

SAMLClient


Monday Mar 23, 2009

Password Derived Keys support in Metro

This feature is about allowing a UsernameToken as a Protection Token under Symmetric Binding .Also we can use this feature as an Initiator Token under Asymmetric Binding.

The Password associated with a Username Token will be used to derive a new Secret Key for the purpose of Integrity and confidentiality .

We require two additional elements to derive the Secret Key from a password.

They are Salt and Iteration. These are not kept secret and must be sent with a UsernameToken. When this key derivation is used the password must not be included in the username token

The folowing example illustrates the use of this key derivation .Also it illustrates the form of UsernameToken which goes on the wire.

<wsse: UsernameToken wsse:Id = ".....">

                 <wsse:Username>Suresh</wsse:Username>

                <wsse11:Salt>Absds/FHfgh/swderfa==</wsse:Salt>

                <wsse11:Iteration>1500</wsse:Iteration>

</wsse: UsernameToken>

Derivation of Secret Key:

A) We generate a 16 byte Random array which will be called Salt.

we set the first byte of the Salt ,thus generated to 01 , if the Key is to be used for MAC or to 02 if the Key is to be used for Encyption

B) The Password and Salt are concatenated in the that order and that value is hashed using SHA1 algorithm

C) The value thus obtained is again hashed using SHA1 and this process is repeated until the total no of hash operations equals to Iteration count

Mathematicaly ,     K1 = SHA1(Password + Salt);

                             K2 = SHA1(K1);

                            ....

                            ....

                             Kn = SHA1(Kn-1); n = iteration count.

D) The Key thus derived is of 160bit value, may be used as a MAC or as a Symmetric key for encryption. When used as a MAC we use the 160 bits and when used for encryption we use only higher order 128 bits( lower order 32 bits will be truncated)

E) If the Iteration value is not specified a default value of atleast 1000 should be used for Iteration.

How it works? The receiving side will use the password (that it already knows) and Salt and Iteration(received from the request) to derive the same key again.After deriving the key the receiver verifies the Signature and decrypts the message.

So using this feature , with just UsernameToken we can Sign and Encrypt the messages with out requiring any other tokens(like X509, Kerboros...)

where we can use this Token? This Token can be used

  i) As an InitiatorToken/InitiatorEncryptionToken of an AsymmetricBinding ,

 ii) As a  ProtectionToken /SignatureToken of a SymmetricBinding and

iii) As an EndorsingSupportingToken/SignedEndorsingEncryptedSupportingToken/

SignedEndorsingSupportingToken/EndorsingEncryptedSupportingToken

Note:The use of this token as ProtectionToken/InitiatorToken/SignatureToken would require WSS 1.1 assertion to be enabled to make use of EncryptedKeySHA1 reference mechanism.

A Sample WSDL policy looks like this:

<wsp:Policy wsu:Id="NewWebServicePortBindingPolicy">
        <wsp:ExactlyOne>
            <wsp:All>
                <wsam:Addressing wsp:Optional="false"/>
                <sp:SymmetricBinding>
                    <wsp:Policy>
                        <sp:ProtectionToken>
                            <wsp:Policy>
                                <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                     <wsp:Policy>                                          
                                           <sp:WssUsernameToken10/>
                                     </wsp:Policy>
                                </sp:UsernameToken>
                            </wsp:Policy>
                        </sp:ProtectionToken>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Strict/>
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp/>                   
                        <sp:OnlySignEntireHeadersAndBody/>
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic128/>
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                    </wsp:Policy>
                </sp:SymmetricBinding>
                <sp:Wss11>
                    <wsp:Policy>
                        <sp:MustSupportRefIssuerSerial/>
                        <sp:MustSupportRefThumbprint/>
                        <sp:MustSupportRefEncryptedKey/>
                    </wsp:Policy>
                </sp:Wss11>
                <sc:ValidatorConfiguration xmlns:sc="http://schemas.sun.com/2006/03/wss/server">
                                <sc:Validator name="usernameValidator" classname="ws.SampleDerivedKeyPasswordValidator" />
                </sc:ValidatorConfiguration>               
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>

You can see one  Username Validator config  in the above policy. A sample UsernameValidator is here

Some sample implementations which use the above PDK concept are uploaded here

Sample with service and client

App2

App2Client

Please note that to run above samples you have to use your own UsernameHandler (currently my username and password are there)

Download link: This feature works with latest Metro builds(24/03/2009). You can download the latest nightly builds from the following link.

Download link for Metro 2.0

https://metro.dev.java.net/servlets/ProjectDocumentList?expandFolder=7638&folderID=10314

References:http://www.oasis-open.org/committees/download.php/16782/wss-v1.1-spec-os-UsernameTokenProfile.pdf

http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/ws-securitypolicy-1.2-spec-os.html

About

Suresh Mandalapu

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today