add priority management for kernel policy
[strongswan.git] / src / charon / sa / authenticator.c
index 3aeb879..8dcfc04 100644 (file)
@@ -6,7 +6,8 @@
  */
 
 /*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -47,7 +48,12 @@ struct private_authenticator_t {
        /**
         * Assigned IKE_SA. Needed to get objects of type prf_t and logger_t.
         */
-       protected_ike_sa_t *ike_sa;
+       ike_sa_t *ike_sa;
+       
+       /**
+        * auth_method to create own signature/mac/whatever..
+        */
+       auth_method_t auth_method;
        
        /**
         * PRF taken from the IKE_SA.
@@ -150,7 +156,7 @@ static chunk_t allocate_octets(private_authenticator_t *this,
        current_pos += other_nonce.len;
        prf->get_bytes(prf, id_with_header_chunk, current_pos);
        
-       this->logger->log_chunk(this->logger,RAW | LEVEL2, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",octets);
+       this->logger->log_chunk(this->logger,RAW | LEVEL2, "octets (message + nonce + prf(Sk_px,Idx)",octets);
        return octets;
 }
 
@@ -177,7 +183,7 @@ static chunk_t build_preshared_secret_signature(private_authenticator_t *this,
        this->prf->set_key(this->prf, key);
        this->prf->allocate_bytes(this->prf, octets, &auth_data);
        chunk_free(&octets);
-       this->logger->log_chunk(this->logger,RAW | LEVEL2, "Authenticated data",auth_data);
+       this->logger->log_chunk(this->logger,RAW | LEVEL2, "authenticated data",auth_data);
 
        return auth_data;
 }
@@ -206,7 +212,7 @@ static status_t verify_auth_data (private_authenticator_t *this,
                                                                                                                        &preshared_secret);
                        if (status != SUCCESS)
                        {
-                               this->logger->log(this->logger, ERROR|LEVEL1, "No shared secret found for %s",
+                               this->logger->log(this->logger, ERROR, "no shared secret found for '%s'",
                                                                  other_id->get_string(other_id));
                                other_id->destroy(other_id);
                                return status;  
@@ -227,13 +233,13 @@ static status_t verify_auth_data (private_authenticator_t *this,
                        }
                        else if (memcmp(auth_data.ptr,my_auth_data.ptr, my_auth_data.len) == 0)
                        {
-                               this->logger->log(this->logger, CONTROL, "Authentication of %s with preshared secret successful",
+                               this->logger->log(this->logger, CONTROL, "authentication of '%s' with preshared secret successful",
                                                                                other_id->get_string(other_id));
                                status = SUCCESS;
                        }
                        else
                        {
-                               this->logger->log(this->logger, CONTROL, "Authentication of %s with preshared secret failed",
+                               this->logger->log(this->logger, ERROR, "authentication of '%s' with preshared secret failed",
                                                                                other_id->get_string(other_id));
                                status = FAILED;
                        }
@@ -243,18 +249,17 @@ static status_t verify_auth_data (private_authenticator_t *this,
                }
                case RSA_DIGITAL_SIGNATURE:
                {
-                       identification_t *other_id = other_id_payload->get_identification(other_id_payload);
-                       rsa_public_key_t *public_key;
                        status_t status;
-                       chunk_t octets, auth_data;
-                       
-                       auth_data = auth_payload->get_data(auth_payload);
-                       
-                       public_key = charon->credentials->get_rsa_public_key(charon->credentials,
-                                                                                                                        other_id);
+                       chunk_t octets;
+                       chunk_t auth_data = auth_payload->get_data(auth_payload);
+                       identification_t *other_id = other_id_payload->get_identification(other_id_payload);
+
+                       rsa_public_key_t *public_key =
+                               charon->credentials->get_trusted_public_key(charon->credentials, other_id);
+
                        if (public_key == NULL)
                        {
-                               this->logger->log(this->logger, ERROR|LEVEL1, "No RSA public key found for %s",
+                               this->logger->log(this->logger, ERROR, "no public key found for '%s'",
                                                                  other_id->get_string(other_id));
                                other_id->destroy(other_id);
                                return NOT_FOUND;       
@@ -265,16 +270,15 @@ static status_t verify_auth_data (private_authenticator_t *this,
                        status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data);
                        if (status == SUCCESS)
                        {
-                               this->logger->log(this->logger, CONTROL, "Authentication of %s with RSA successful",
+                               this->logger->log(this->logger, CONTROL, "authentication of '%s' with RSA successful",
                                                                                other_id->get_string(other_id));
                        }
                        else
                        {
-                               this->logger->log(this->logger, CONTROL, "Authentication of %s with RSA failed",
+                               this->logger->log(this->logger, ERROR, "authentication of '%s' with RSA failed",
                                                                                other_id->get_string(other_id));
                        }
                        
-                       public_key->destroy(public_key);
                        other_id->destroy(other_id);
                        chunk_free(&octets);
                        return status;
@@ -295,10 +299,8 @@ static status_t compute_auth_data (private_authenticator_t *this,
                                                                        chunk_t other_nonce,
                                                                        id_payload_t *my_id_payload,
                                                                        bool initiator)
-{
-       connection_t *connection = this->ike_sa->get_connection(this->ike_sa);
-       
-       switch(connection->get_auth_method(connection))
+{      
+       switch(this->auth_method)
        {
                case SHARED_KEY_MESSAGE_INTEGRITY_CODE:
                {
@@ -313,7 +315,7 @@ static status_t compute_auth_data (private_authenticator_t *this,
 
                        if (status != SUCCESS)
                        {
-                               this->logger->log(this->logger, ERROR|LEVEL1, "No shared secret found for %s",
+                               this->logger->log(this->logger, ERROR, "no shared secret found for %s",
                                                                  my_id->get_string(my_id));
                                my_id->destroy(my_id);
                                return status;  
@@ -332,38 +334,61 @@ static status_t compute_auth_data (private_authenticator_t *this,
                }
                case RSA_DIGITAL_SIGNATURE:
                {
-                       identification_t *my_id = my_id_payload->get_identification(my_id_payload);
-                       rsa_private_key_t *private_key;
-                       status_t status;
+                       char buf[BUF_LEN];
                        chunk_t octets, auth_data;
+                       status_t status = NOT_FOUND;
+                       rsa_public_key_t  *my_pubkey;
+                       rsa_private_key_t *my_key;
+
+                       identification_t  *my_id = my_id_payload->get_identification(my_id_payload);
                        
-                       private_key = charon->credentials->get_rsa_private_key(charon->credentials, my_id);
-                       if (private_key == NULL)
+                       this->logger->log(this->logger, CONTROL|LEVEL1, "looking for public key belonging to '%s'",
+                                                         my_id->get_string(my_id));
+
+                       my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
+                       if (my_pubkey == NULL)
                        {
-                               this->logger->log(this->logger, ERROR|LEVEL1, "No RSA private key found for %s",
+                               this->logger->log(this->logger, ERROR, "no public key found for '%s'",
                                                                  my_id->get_string(my_id));
-                               my_id->destroy(my_id);
-                               return NOT_FOUND;       
+                               goto end_rsa;
                        }
-                       my_id->destroy(my_id);
+                       this->logger->log(this->logger, CONTROL|LEVEL2, "matching public key found");
                        
+                       chunk_to_hex(buf, BUF_LEN, my_pubkey->get_keyid(my_pubkey));
+                       this->logger->log(this->logger, CONTROL|LEVEL1, "looking for private key with keyid %s", buf);
+
+                       my_key = charon->credentials->get_rsa_private_key(charon->credentials, my_pubkey);
+                       if (my_key == NULL)
+                       {
+                               char buf[BUF_LEN];
+
+                               chunk_to_hex(buf, BUF_LEN, my_pubkey->get_keyid(my_pubkey));
+                               this->logger->log(this->logger, ERROR, "no private key found with for %s with keyid %s",
+                                                                 my_id->get_string(my_id), buf);
+                               goto end_rsa;
+                       }
+                       this->logger->log(this->logger, CONTROL|LEVEL2, "matching private key found");
+
                        octets = this->allocate_octets(this,last_sent_packet,other_nonce,my_id_payload,initiator);
-                       
-                       status = private_key->build_emsa_pkcs1_signature(private_key, HASH_SHA1, octets, &auth_data);
+                       status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data);
                        chunk_free(&octets);
+
                        if (status != SUCCESS)
                        {
-                               private_key->destroy(private_key);
-                               return status;
+                               my_key->destroy(my_key);
+                               goto end_rsa;
                        }
                        
                        *auth_payload = auth_payload_create();
                        (*auth_payload)->set_auth_method(*auth_payload, RSA_DIGITAL_SIGNATURE);
                        (*auth_payload)->set_data(*auth_payload, auth_data);
 
-                       private_key->destroy(private_key);
+                       my_key->destroy(my_key);
                        chunk_free(&auth_data);
-                       return SUCCESS;
+
+               end_rsa:
+                       my_id->destroy(my_id);
+                       return status;
                }
                default:
                {
@@ -383,7 +408,7 @@ static void destroy (private_authenticator_t *this)
 /*
  * Described in header.
  */
-authenticator_t *authenticator_create(protected_ike_sa_t *ike_sa)
+authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method)
 {
        private_authenticator_t *this = malloc_thing(private_authenticator_t);
 
@@ -398,6 +423,7 @@ authenticator_t *authenticator_create(protected_ike_sa_t *ike_sa)
        
        /* private data */
        this->ike_sa = ike_sa;
+       this->auth_method = auth_method;
        this->prf = this->ike_sa->get_prf(this->ike_sa);
        this->logger = logger_manager->get_logger(logger_manager, IKE_SA);