[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[iaik-jce] Client authentication - Meaning of the 3 args to getCertificate() method



Taking clues from the explanations received from IAIK, I have coded
the getCertificate() method as follows :- (only part shown)
Assume that we have only RSA Certificates for the Server and Client side.
In fact, we only have one Certificate Chain at each end today.

public SSLCertificate getCertificate
        (byte[] certificateTypes, Principal[] certificateAuthorities, String strNegKeyExchAlg) {
            -------------
            /*
            a-2) Check for certificateTypes :-
                   Check if EACH of the Client Certificate's type matches with one of those approved by the Server.
                   At the end if bCertType is true, we are sure that EACH of the Certificates' types in the Client Chain
                   matches with some approved Server type.
            */
            boolean bCertType   = false ;
            /*
            The following logic is based on hints from Dieter Bratko of IAIK about the difference between a
            X_sign Cert which has a signing capability ie, the Cert contains a Public key,
            and X_fixed_dh Cert which has NO signing capability ie, no Priv/Publ Keys, only DH pars.
            Here, we consider only rsa_sign, dss_sign is not considered.
            */
            // EACH Cl Cert's certificateTypes compared with the Server certificateType ("rsa_sign" only)
            for ( int i = 0 ; i < clientCertChain.length ; i++ ) {
                bCertType = false ; // to ensure that EACH Cert in the chain matches with the Server's (rsa_sign)
                for ( int j = 0 ; j < certificateTypes.length ; j++ ) {  // rsa_sign from WL's Tengah Server
                    if ( certificateTypes[j] == ClientTrustDecider.rsa_sign ) { // Check only for rsa_sign
                        if ( (clientCertChain[i].getPublicKey().getAlgorithm()).equalsIgnoreCase("RSA") ) { // F
                            bCertType = true ;
                            break ;     // NOT continue here!   break out of for - j loop if we get a match.
                        }
                        else {
                            bCertType = false ;
                        }
                    }
                } // for - j loop
            }

            // Finally, if bCertType is true
            if (bCertType)
            { ------- }

            /*
            b-2) Check for certificateAuthorities :-
                   Check if EACH of the Client Certificate's SubjectDN matches with one of the certificateAuthorities
                   approved by the Server.
                   At the end if bSubjectDNType is true, we are sure that EACH of the Certificates' SubjectDN in the
                   Client Chain matches with some approved Server type.
                   Eg : Received from WL's Tengah Server :
                   C: INDIA , SP: Karnataka , O: Hewlett Packard ISO , O: Testing by Sundar Krishnan , OU: ICOM
            */
            boolean bSubjectDNType   = false ;
            for ( int i = 0 ; i < clientCertChain.length ; i++ ) {
                bSubjectDNType = false ;
                for ( int j = 0 ; j < certificateAuthorities.length ; j++ ) {
                    if ( ( clientCertChain[i].getSubjectDN() ).equals(certificateAuthorities[j]) ) {
                        // EACH Cl Cert's CA with ANY of the Server CAs
                        bSubjectDNType = true ;
                        break ;     // NOT continue here!   break out of for - j loop if we get a match.
                    }
                }
                // If no match with the Server's, break with false.
                if (!bSubjectDNType) break ;
            }
            if (bSubjectDNType)
            { ------- }

            /* c-2) Check for KeyExchangeAlgorithm :-
                       Check if EACH of the Client Certificate's KeyExchangeAlgorithm matches with negotiated
                       KeyExchangeAlgorithm.
            */
            boolean bKeyExchAlg   = false ;
            /*
            At this moment, since the Server and the Client have only a single type, we are only checking for
            algorithms beginning with RSA.
            If the Client has enabled a whole lot of CipherSuites, and the negotiated KeyExchangeAlgorithm
            is not either RSA_EXPORT or RSA, we cannot proceed further because the Client Certs are now
            RSA_EXPORT based only.

            However, a check if the Cert is an RSA has already been done above in bCertType test.
            We therefore do not have to repeat this line here :
                if ( (clientCertChain[i].getPublicKey().getAlgorithm()).equalsIgnoreCase("RSA") )  // F
            Later, it can be further developed to check even with strNegKeyExchAlg.startsWith("DHE_RSA"))
            */
            if ( strNegKeyExchAlg.startsWith("RSA") ) {
                bKeyExchAlg = true ;
            }

            if (bKeyExchAlg)
            { ------- }

            // Finally, only if all the 3 booleans are true, return an SSLCertificate, else null.
            if ( (bCertType) && (bSubjectDNType) && (bKeyExchAlg) ) {
                return new SSLCertificate ( clientCertChain ) ;
            }
            else return null ;

Pl confirm that the logic for certificateTypes (bCertType) is OK.
From above, we can see that there is hardly any difference in the checks between
certificateTypes check and KeyExchangeAlgorithm check. Pl comment/suggest
if I have to change the logic for bKeyExchAlg.
 

2) Wrt iSaSiLk 2.0 Final User Manual :-
In P76, under 3.4.1.1.5.3 public interface ClientTrustDecider :-
For rsa_ephemeral_dh, it says that "...the ephemeral Diffie Hellman parameters
are sent with the Client Key Exchange message and have to match to the
DH parameters the client has received within the server key exchange message;..."
However, the SSL 3.0 Spec says that ServerKeyExchange message is not used
if the server certificate contains Diffie-Hellman parameters.
Pl comment on this apparent difference.

3) The SSL spec says that ServerKeyExchange is sent if :
a) the server has no cert.
b) has a cert only used for signing ( eg, DSS or sign-only RSA)
c) fortezza/DMS key exchange is used
Perhaps, we should add one more :- ( Pl confirm) (Taken from P9 of IAIK Manual)
d ??) if the CipherSuite is exportable and the public key is > 512 bits,
the server may have to send the Temp Encryption Key in a separate
ServerKeyExchange msg. Is my understanding correct ?

4) Pl confirm that Certs types as indicated in P36 (3.3.2) should be :
RSA, DH, DSS    and not
RSA, DH, DSA.

Thanks in advance.

Rgds

Sundar Krishnan

***************************************************
 
 

Dieter Bratko wrote:


The certificateTypes parameter of ClientTrustDecider´s getCertificate method denotes the types of certificates the server requests, in the
server´s preference order.
 
Except for rsa_fixed_dh and dss_fixed_dh types, where the client certificate has to contain fixed DH parameters, all the other types indicate
certificates that have signing capability and therefore require a CertificateVerify message.
So, for instance, rsa_sign only requests a certificate containing a RSA public key; and you don´t need a byte of the X509Certificate class to be
compared againts the type byte (1a).
The differance between rsa_sign and rsa_fixed_dh is that rsa_sign requests a certificate with a RSA public key, whereas rsa_fixed_dh requies
a certificate with DH parameters and therefore has no signing capability. rsa_ephemaral_dh and dss_ephemeral_dh denote certificates
containing a public RSA/DSA (signing capability) key; the DH parameters are sent with a Client Key Exchange message.
 
2) Yes, the keyExchangeAlgorithm denotes the key exchange algorithm of the currently active cipherSuite set at the beginning of the
handshake phase.
 
3) Principal[] certificateAuthorities denotes the subjectDNs
 
Dieter Bratko