optional certificate-based peer authentication on TLS server side
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 15 Aug 2010 11:02:57 +0000 (13:02 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 15 Aug 2010 11:02:57 +0000 (13:02 +0200)
src/libcharon/plugins/eap_tls/eap_tls.c
src/libcharon/plugins/eap_ttls/eap_ttls.c
src/libtls/tls.c
src/libtls/tls.h
src/libtls/tls_server.c
src/libtls/tls_server.h

index e4f12d7..849f038 100644 (file)
@@ -433,8 +433,8 @@ static eap_tls_t *eap_tls_create(identification_t *server,
                .is_server = is_server,
        );
        /* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
-       this->tls = tls_create(is_server, server, peer, "client EAP encryption",
-                                                  NULL);
+       this->tls = tls_create(is_server, server, peer, TRUE,
+                                                  "client EAP encryption", NULL);
 
        return &this->public;
 }
index 56713c3..dd24f40 100644 (file)
@@ -441,8 +441,8 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
                .is_server = is_server,
        );
        /* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
-       this->tls = tls_create(is_server, server, peer, "ttls keying material",
-                                                  application);
+       this->tls = tls_create(is_server, server, peer, FALSE,
+                                                  "ttls keying material", application);
        return &this->public;
 }
 
index 24f442c..e3be79d 100644 (file)
@@ -178,8 +178,8 @@ METHOD(tls_t, destroy, void,
  * See header
  */
 tls_t *tls_create(bool is_server, identification_t *server,
-                                 identification_t *peer, char *msk_label,
-                                 tls_application_t *application)
+                                 identification_t *peer, bool request_peer_auth,
+                                 char *msk_label, tls_application_t *application)
 {
        private_tls_t *this;
 
@@ -205,7 +205,8 @@ tls_t *tls_create(bool is_server, identification_t *server,
        if (is_server)
        {
                this->handshake = &tls_server_create(&this->public, this->crypto,
-                                                                               this->server, this->peer)->handshake;
+                                                                               this->server, this->peer,
+                                                                               request_peer_auth)->handshake;
        }
        else
        {
index ea66b76..95ec601 100644 (file)
@@ -161,15 +161,16 @@ struct tls_t {
 /**
  * Create a tls instance.
  *
- * @param is_server            TRUE to act as server, FALSE for client
- * @param server               server identity
- * @param peer                 peer identity
- * @param msk_label            ASCII string constant used as seed for MSK PRF
- * @param application  higher layer application or NULL if none
- * @return                             TLS stack
+ * @param is_server                    TRUE to act as server, FALSE for client
+ * @param server                       server identity
+ * @param peer                         peer identity
+ * @param request_peer_auth    TRUE to request certificate-based peer authentication
+ * @param msk_label                    ASCII string constant used as seed for MSK PRF
+ * @param application          higher layer application or NULL if none
+ * @return                                     TLS stack
  */
 tls_t *tls_create(bool is_server, identification_t *server,
-                                 identification_t *peer, char *msk_label,
-                                 tls_application_t *application);
+                                 identification_t *peer, bool request_peer_auth,
+                                 char *msk_label, tls_application_t *application);
 
 #endif /** TLS_H_ @}*/
index 673b201..2b2845e 100644 (file)
@@ -84,6 +84,11 @@ struct private_tls_server_t {
        char server_random[32];
 
        /**
+        * Does the server request a peer authentication?
+        */
+       bool request_peer_auth;
+
+       /**
         * Auth helper for peer authentication
         */
        auth_cfg_t *peer_auth;
@@ -332,8 +337,12 @@ METHOD(tls_handshake_t, process, status_t,
                        {
                                return process_certificate(this, reader);
                        }
-                       expected = TLS_CERTIFICATE;
-                       break;
+                       if (this->request_peer_auth)
+                       {
+                               expected = TLS_CERTIFICATE;
+                               break;
+                       }
+                       /* otherwise fall through to next state */
                case STATE_CERT_RECEIVED:
                        if (type == TLS_CLIENT_KEY_EXCHANGE)
                        {
@@ -346,8 +355,15 @@ METHOD(tls_handshake_t, process, status_t,
                        {
                                return process_cert_verify(this, reader);
                        }
-                       expected = TLS_CERTIFICATE_VERIFY;
-                       break;
+                       if (this->request_peer_auth)
+                       {
+                               expected = TLS_CERTIFICATE_VERIFY;
+                               break;
+                       }
+                       else
+                       {
+                               return INVALID_STATE;
+                       }
                case STATE_CIPHERSPEC_CHANGED_IN:
                        if (type == TLS_FINISHED)
                        {
@@ -547,7 +563,11 @@ METHOD(tls_handshake_t, build, status_t,
                case STATE_HELLO_SENT:
                        return send_certificate(this, type, writer);
                case STATE_CERT_SENT:
-                       return send_certificate_request(this, type, writer);
+                       if (this->request_peer_auth)
+                       {
+                               return send_certificate_request(this, type, writer);
+                       }
+                       /* otherwise fall through to next state */
                case STATE_CERTREQ_SENT:
                        return send_hello_done(this, type, writer);
                case STATE_CIPHERSPEC_CHANGED_OUT:
@@ -574,7 +594,8 @@ METHOD(tls_handshake_t, cipherspec_changed, bool,
 METHOD(tls_handshake_t, change_cipherspec, bool,
        private_tls_server_t *this)
 {
-       if (this->state == STATE_CERT_VERIFY_RECEIVED)
+       if ((this->request_peer_auth && this->state == STATE_CERT_VERIFY_RECEIVED) ||
+          (!this->request_peer_auth && this->state == STATE_KEY_EXCHANGE_RECEIVED))
        {
                this->crypto->change_cipher(this->crypto, TRUE);
                this->state = STATE_CIPHERSPEC_CHANGED_IN;
@@ -602,7 +623,8 @@ METHOD(tls_handshake_t, destroy, void,
  * See header
  */
 tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
-                                                       identification_t *server, identification_t *peer)
+                                                       identification_t *server, identification_t *peer,
+                                                       bool request_peer_auth)
 {
        private_tls_server_t *this;
 
@@ -620,6 +642,7 @@ tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
                .server = server,
                .peer = peer,
                .state = STATE_INIT,
+               .request_peer_auth = request_peer_auth,
                .peer_auth = auth_cfg_create(),
                .server_auth = auth_cfg_create(),
        );
index 6dc26cd..a15d54f 100644 (file)
@@ -43,6 +43,7 @@ struct tls_server_t {
  * Create a tls_server instance.
  */
 tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
-                                                       identification_t *server, identification_t *peer);
+                                                       identification_t *server, identification_t *peer,
+                                                       bool request_peer_auth);
 
 #endif /** TLS_SERVER_H_ @}*/