axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Shyam Shukla " <shyam_shu...@persistent.co.in>
Subject RE: Adding BST in SOAP request header without using Keystore
Date Mon, 20 Nov 2006 15:32:58 GMT
Hi Fred.

 

Thanks for reply and I apologize for not being clear in the subject line. 

Actually, I have to just include the X509 security token as a Binary
Security Token in SOAP WS-Security header i.e I want to generate a
RequestSecurityToken with a X509Security Token, without using Keystore.

 

While I am sending request, I will only have client cert in a string format
and don't have private key of the issuer.

My client program also has to support multi-threading so it's not a feasible
solution to store client certificate for each user in keystore
programmatically at run-time.

 

What you suggested to implement Crypto interface is what I am trying to
achieve but I have a doubt, how would I pass client certificate which is in
string format to MyMerlin class?

I am giving below the code snipped for the same:

 

<< Start of  MyMerlin Class>>

 

public class MyMerlin implements Crypto

{

            protected static CertificateFactory certFact;

            protected Properties properties = null;

            static String SKI_OID = "2.5.29.14";

 

            public MyMerlin(Properties properties) throws
CredentialException, IOException

            {

            this(properties,MyMerlin.class.getClassLoader());

    }

 

    public MyMerlin(Properties properties, ClassLoader loader) throws
CredentialException, IOException

            {

        if (properties == null)

                        {

            return;

        }

        this.properties = properties;

     

    }

 

            

public X509Certificate loadCertificate(InputStream in) throws
WSSecurityException

            {

        X509Certificate cert = null;

        try

                        {

            cert = (X509Certificate)
getCertificateFactory().generateCertificate(in);

        }

                        catch (CertificateException e)

                        {

            throw new
WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"parseError");

        }

        return cert;

    }

 

            public X509Certificate[] getX509Certificates(byte[] data,
boolean reverse) throws WSSecurityException

            {

        InputStream in = new ByteArrayInputStream(data);

        CertPath path = null;

        try

                        {

            path = getCertificateFactory().generateCertPath(in);

        }

                        catch (CertificateException e)

                        {

            throw new
WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"parseError");

        }

        List l = path.getCertificates();

        X509Certificate[] certs = new X509Certificate[l.size()];

        Iterator iterator = l.iterator();

        for (int i = 0; i < l.size(); i++)

                        {

            certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate)
iterator.next();

        }

        return certs;

    }

 

            public byte[] getCertificateData(boolean reverse,
X509Certificate[] certs) throws WSSecurityException

            {

        Vector<X509Certificate> list = new Vector<X509Certificate>();

        for (int i = 0; i < certs.length; i++)

                        {

            if (reverse)

                                    {

                list.insertElementAt(certs[i], 0);

            }

                                    else

                                    {

                list.add(certs[i]);

            }

        }

        try 

                        {

            CertPath path = getCertificateFactory().generateCertPath(list);

            return path.getEncoded();

        } 

                        catch (CertificateEncodingException e)

                        {

            throw new
WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"encodeError");

        }

                        catch (CertificateException e)

                        {

            throw new
WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"parseError");

        }

    }

 

            public PrivateKey getPrivateKey(String alias, String password)
throws Exception

            {

            return null;

            }

 

            public X509Certificate[] getCertificates(String alias) throws
WSSecurityException

            {

       return null;

    }

 

            

            public String getAliasForX509Cert(Certificate cert) throws
WSSecurityException

            {

       return null;

    }

 

            public String getAliasForX509Cert(String issuer) throws
WSSecurityException

            {

        return null;

    }

 

            public String getAliasForX509Cert(String issuer, BigInteger
serialNumber) throws WSSecurityException

            {

        return null;

    }

 

            public String getAliasForX509Cert(byte[] skiBytes) throws
WSSecurityException

            {

        return null;

    }

 

            public String getDefaultX509Alias()

            {

                        return null;

    }

 

            public byte[] getSKIBytesFromCert(X509Certificate cert) throws
WSSecurityException

            {

        byte[] derEncodedValue = cert.getExtensionValue(SKI_OID);

 

        if (cert.getVersion() < 3 || derEncodedValue == null)

                        {

            PublicKey key = cert.getPublicKey();

            if (!(key instanceof RSAPublicKey))

                                    {

                throw new WSSecurityException(1, "noSKIHandling", new
Object[]{"Support for RSA key only"});

            }

            byte[] encoded = key.getEncoded();

            // remove 22-byte algorithm ID and header

            byte[] value = new byte[encoded.length - 22];

            System.arraycopy(encoded, 22, value, 0, value.length);

            MessageDigest sha;

            try 

                                    {

                sha = MessageDigest.getInstance("SHA-1");

            }

                                    catch (NoSuchAlgorithmException ex)

                                    {

                throw new WSSecurityException(1, "noSKIHandling", new
Object[]{"Wrong certificate version (<3) and no SHA1 message digest
availabe"});

            }

            sha.reset();

            sha.update(value);

            return sha.digest();

        }

 

        byte abyte0[] = new byte[derEncodedValue.length - 4];

 

        System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length);

        return abyte0;

    }

 

            public String getAliasForX509CertThumb(byte[] thumb) throws
WSSecurityException

            {

         return null;

    }

 

            public KeyStore getKeyStore()

            {

                         return null;

    }

 

            public synchronized CertificateFactory getCertificateFactory()
throws WSSecurityException

            {

        if (certFact == null)

                        {

            try

                                    {

               certFact = CertificateFactory.getInstance("X.509");

            }

                                    catch (CertificateException e)

                                    {

                throw new
WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"unsupportedCertType");

            }

                                    

        }

        return certFact;

    }

 

            public boolean validateCertPath(X509Certificate[] certs) throws
WSSecurityException

            {

                return true;

    }

 

            public String[] getAliasesForDN(String subjectDN) throws
WSSecurityException

            {

                        return null;      

    }

}

 

<< End of  MyMerlin Class>>

 

The only entry that I made in crypto.properties file is as below:

org.apache.ws.security.crypto.provider=sample.security.MyMerlin

 

Is this correct?

 

What all are changes required in axis2.xml file for outgoing request?

At the present, my axis2.xml looks like as below for the outgoing request:

 

<parameter name="OutflowSecurity">

      <action>

      <items>Timestamp Signature</items>

        <signaturePropFile>crypto.properties</signaturePropFile>

 
<signatureParts>{Element}{http://schemas.xmlsoap.org/ws/2004/03/addressing}T
o;{Element}{http://schemas.xmlsoap.org/ws/2004/03/addressing}ReplyTo;{Elemen
t}{http://schemas.xmlsoap.org/ws/2004/03/addressing}Action;{Element}{http://
schemas.xmlsoap.org/ws/2004/03/addressing}MessageID;{Element}{http://schemas
.xmlsoap.org/soap/envelope/}Body;{Element}{http://docs.oasis-open.org/wss/20
04/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp</signatureParts>

 
<enableSignatureConfirmation>false</enableSignatureConfirmation>

               

      </action>

    </parameter>

 

With this setting I am getting error "Empty username and/or passwrod".

As I believe, when I am not using keystore then password should not be
required but not sure about user name.

 

I am sorry for spamming your mailbox with this large email but I had the
only option you let you guys know about my problem.

 

 

 

Thanks in Advance,
Shyam Shukla


  _____  

From: Fred Dushin [mailto:fdushin@iona.com] 
Sent: Monday, November 20, 2006 8:02 PM
To: Shyam Shukla
Cc: wss4j-dev@ws.apache.org; axis-dev@ws.apache.org
Subject: Re: Signing SOAP request without using Keystore

 

I'm a bit confused by your question, because your subject mentions the need
to sign a SOAP message, but the body of your message talks about "creating a
SOAP request with an X.509 security token".  I assume by the latter you mean
sign the message, right?  In other words, you are not just sending the X.509
certificate though the SOAP header, per the X.509 profile in the WS-Security
specification.  Correct?

I hate to be the bearer of bad news, but you need a private key in order to
sign a message (at least if the recipient is using a public-key to verify
the signature).  Signing data with the public key in a certificate doesn't
really make any sense, from a security perspective.

Getting back to the question about Merlin, if you are only using the WSS4j
toolkit to sign outbound messages, then you should be able to get away with
throwing NO_IMPLEMENTs (or their equivalent) from the Crypto operations that
would not be used (e.g., for encrypting, verifying, or decrypting messages).
I'm afraid to say that I could not say without some experimentation which
operations need to be implemented just for signing.  Probably the better
approach would be just to populate a Keystore programatically with the keys
and certs you already have, and then pass that to the Crypto implementation
of your choice, but as I said in a previous email, doing so requires a patch
to the toolkit.

-Fred

Shyam Shukla wrote: 

Hi All,

 

I am re-posting my query as I don't get any response from my previous post.

My problem is I am required to create a SOAP Request with X509 security
token but can not use certificate from any persistent store like keystore
that is used by axis2 framework.

Actually, I get certificate at run time in a string format and using this
certificate I will have to sign the request. 

Earlier, I was suggested to implement Crypto interface and assign this
implementation to "org.apache.ws.security.crypto.provider" key in
crypto.properties file, so I went through the Merlin class which implements
Crypto interface to have the understanding of signing of SOAP request but
this approach doesn't help me as it has some methods like
getPrivateKey(String alias, String password), getCertificates(String alias),
getAliasForX509Cert(Certificate cert) etc. which uses keystore. So I can not
implement Crypto interface because it has some methods which require
keystore to be present.

 

Can anyone suggest me the way to implement this scenario?

 

 

Best Regards,
Shyam Shukla




 

DISCLAIMER ========== This e-mail may contain privileged and confidential
information which is the property of Persistent Systems Pvt. Ltd. It is
intended only for the use of the individual or entity to which it is
addressed. If you are not the intended recipient, you are not authorized to
read, retain, copy, print, distribute or use this message. If you have
received this communication in error, please notify the sender and delete
all copies of this message. Persistent Systems Pvt. Ltd. does not accept any
liability for virus infected mails.


DISCLAIMER
==========
This e-mail may contain privileged and confidential information which is the property of Persistent
Systems Pvt. Ltd. It is intended only for the use of the individual or entity to which it
is addressed. If you are not the intended recipient, you are not authorized to read, retain,
copy, print, distribute or use this message. If you have received this communication in error,
please notify the sender and delete all copies of this message. Persistent Systems Pvt. Ltd.
does not accept any liability for virus infected mails.

Mime
View raw message