I set the following for the global context which is used to create the 
connection:
        // Set the SSL certificate verify mode
        SSL_CTX_set_verify(_globalContext, SSL_VERIFY_PEER, NULL);

Then the server requests the peer (i.e. the client) for a certificate during 
the handshake, which the client can either ignore, or provide.

Then, right after SSL_accept() returns > 0, i.e. now we are ready to check the 
certificate,  I add the following code to see if the client provided a 
certificate and whether it is acceptable.
       Check that SSL_get_verify_result(_connContext) == X509_V_OK,  // This 
checks for the validity of the certificate chain.


        // Did the client provide a certificate?
        cert = SSL_get_peer_certificate(_connContext);
        if (cert == NULL) { // Client provided no certificate.
         // mark it as "not provided certificate during handshake" and give it 
lower privileges.
         // Otherwise check the certificate for acceptability and if that check 
passes give it higher privileges.

Hope that helps.

The other option is to do a handshake without asking for a client certificate 
first, then do a re-handshake and ask the client for a certificate when 
required.

Ashish
______________________________________________________________________________________________________
Ashish V. Thapliyal, Security Architect, Citrix Online Division, 6500 Hollister 
Ave, Goleta, CA 93117. V: +1 (805) 690 2908.






From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] 
On Behalf Of Michael Prinzinger
Sent: Wednesday, September 23, 2009 1:05 PM
To: openssl-users@openssl.org
Subject: verify client certificate at a later point

Dear OpenSSL group,

I have a somewhat curious setting (without CAs) about routing information along 
several nodes:

[1] first an unkown client establishes a connection to a known server
  thus I set
SSL_CTX_set_verify(this->ctx, SSL_VERIFY_NONE, NULL);

  and let the client verify the servers certificate, like this
    X509* x509 = SSL_get_peer_certificate(s);
    CHECK(x509 != NULL);

    //check certificate
    long certVerifyResults = SSL_get_verify_result(s);
    if(certVerifyResults != X509_V_OK)
        throw SSLException("Error! Certificate could not be verified.\n);

    //free x509
    X509_free(x509);


[2] now a secure connection is established
   on it the server receives data encrypted with the servers public key, so 
only it can read it
   in the data is information about the next node and the previous node
   now the server knows the ssl certificate of the previous node and thus wants 
to check it,
   since the verify mode is still set to server only, we set it a new
SSL_CTX_set_verify(this->ctx, SSL_VERIFY_PEER | 
SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);

[3] if the server now runs the code above
    X509* x509 = SSL_get_peer_certificate(s);
    CHECK(x509 != NULL);

    //check certificate
    long certVerifyResults = SSL_get_verify_result(s);
    if(certVerifyResults != X509_V_OK)
        throw SSLException("Error! Certificate could not be verified.\n);

    //free x509
    X509_free(x509);

x509 will be NULL.

This is probably because the handshake has already taken place. So there simply 
is no client certificate.
Now I am trying to find a way around this problem, but failed so far.
It would be nice to either find a way that both certificates are exchanged 
during handshae, but only the server one is verified at first
or to find a way to request a certificate from the client at a later point.

Has anyone an idea, how this could be achieved with the OpenSSL API?


Thank You Very Much!

Michael



Reply via email to