Own keys, now filled and used by myself()
authorEdouard Tisserant
Tue, 10 May 2016 13:48:01 +0200
changeset 588b7f954296900
parent 587 ed8aa5e5b02c
child 589 bdff8843f086
Own keys, now filled and used by myself()
src/keymanagement.c
src/pEpEngine.c
     1.1 --- a/src/keymanagement.c	Tue May 10 12:28:40 2016 +0200
     1.2 +++ b/src/keymanagement.c	Tue May 10 13:48:01 2016 +0200
     1.3 @@ -190,20 +190,16 @@
     1.4                      return PEP_OUT_OF_MEMORY;
     1.5                  }
     1.6  
     1.7 -                if (identity->comm_type == PEP_ct_unknown) {
     1.8 -                    if (_comm_type_key != PEP_ct_compromized && _comm_type_key != PEP_ct_unknown) {
     1.9 +                if (_comm_type_key != PEP_ct_compromized &&
    1.10 +                    _comm_type_key != PEP_ct_unknown)
    1.11 +                {
    1.12 +                    if (identity->comm_type == PEP_ct_unknown ||
    1.13 +                        _comm_type_key > identity->comm_type)
    1.14 +                    {
    1.15                          identity->comm_type = _comm_type_key;
    1.16                          _fpr = _keylist->value;
    1.17                      }
    1.18                  }
    1.19 -                else {
    1.20 -                    if (_comm_type_key != PEP_ct_compromized && _comm_type_key != PEP_ct_unknown) {
    1.21 -                        if (_comm_type_key > identity->comm_type) {
    1.22 -                            identity->comm_type = _comm_type_key;
    1.23 -                            _fpr = _keylist->value;
    1.24 -                        }
    1.25 -                    }
    1.26 -                }
    1.27              }
    1.28  
    1.29              if (_fpr) {
    1.30 @@ -257,7 +253,6 @@
    1.31  {
    1.32      pEp_identity *stored_identity;
    1.33      PEP_STATUS status;
    1.34 -    stringlist_t *keylist = NULL;
    1.35  
    1.36      assert(session);
    1.37      assert(identity);
    1.38 @@ -295,9 +290,27 @@
    1.39              }
    1.40              identity->fpr_size = stored_identity->fpr_size;
    1.41          }
    1.42 +
    1.43 +        // Backward compatibility, not check that stored key is indeed own key
    1.44 +
    1.45 +    }
    1.46 +    else if (!EMPTYSTR(identity->fpr))
    1.47 +    {
    1.48 +        // App must have a good reason to give fpr, such as explicit
    1.49 +        // import of private key, or similar.
    1.50 +
    1.51 +        // Take given fpr as-is, and consider it as own-key.
    1.52 +
    1.53 +        status = own_key_add(session, identity->fpr);
    1.54 +        assert(status == PEP_STATUS_OK);
    1.55 +        if (status != PEP_STATUS_OK) {
    1.56 +            return status;
    1.57 +        }
    1.58      }
    1.59      else
    1.60      {
    1.61 +        stringlist_t *keylist = NULL;
    1.62 +
    1.63          free(identity->fpr);
    1.64          identity->fpr_size = 0;
    1.65          
    1.66 @@ -308,34 +321,66 @@
    1.67          
    1.68          if (keylist != NULL && keylist->value != NULL)
    1.69          {
    1.70 -            // BUG : Vulnerable to auto-key-import poisoning.
    1.71 -            //       Attacker's key with forged userId could have been
    1.72 -            //       auto imported from already received email and be used here
    1.73 +            char *_fpr = NULL;
    1.74 +            identity->comm_type = PEP_ct_unknown;
    1.75 +
    1.76 +            stringlist_t *_keylist;
    1.77 +            for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
    1.78 +                bool is_own = false;
    1.79 +                
    1.80 +                status = own_key_is_listed(session, _keylist->value, &is_own);
    1.81 +                assert(status == PEP_STATUS_OK);
    1.82 +                if (status != PEP_STATUS_OK) {
    1.83 +                    free_stringlist(keylist);
    1.84 +                    return status;
    1.85 +                }
    1.86 +
    1.87 +                // TODO : also accept synchronized device group keys ?
    1.88 +                
    1.89 +                if (is_own)
    1.90 +                {
    1.91 +                    PEP_comm_type _comm_type_key;
    1.92 +                    
    1.93 +                    status = get_key_rating(session, _keylist->value, &_comm_type_key);
    1.94 +                    assert(status != PEP_OUT_OF_MEMORY);
    1.95 +                    if (status == PEP_OUT_OF_MEMORY) {
    1.96 +                        free_stringlist(keylist);
    1.97 +                        return PEP_OUT_OF_MEMORY;
    1.98 +                    }
    1.99 +                    
   1.100 +                    if (_comm_type_key != PEP_ct_compromized &&
   1.101 +                        _comm_type_key != PEP_ct_unknown)
   1.102 +                    {
   1.103 +                        if (identity->comm_type == PEP_ct_unknown ||
   1.104 +                            _comm_type_key > identity->comm_type)
   1.105 +                        {
   1.106 +                            identity->comm_type = _comm_type_key;
   1.107 +                            _fpr = _keylist->value;
   1.108 +                        }
   1.109 +                    }
   1.110 +                }
   1.111 +            }
   1.112              
   1.113 -            // TODO : iterate over list to elect best key
   1.114 -            // TODO : discard keys which aren't private
   1.115 -            // TODO : discard keys which aren't either
   1.116 -            //             - own generated key
   1.117 -            //             - own from synchronized device group
   1.118 -            //             - already fully trusted as a public key of known
   1.119 -            //               identity, for that same address
   1.120 -            //               (case of imported key for mailing lists)
   1.121 -            
   1.122 -            identity->fpr = strdup(keylist->value);
   1.123 -            assert(identity->fpr);
   1.124 -            if (identity->fpr == NULL)
   1.125 +            if (_fpr)
   1.126              {
   1.127 -                return PEP_OUT_OF_MEMORY;
   1.128 +                identity->fpr = strdup(_fpr);
   1.129 +                assert(identity->fpr);
   1.130 +                if (identity->fpr == NULL)
   1.131 +                {
   1.132 +                    free_stringlist(keylist);
   1.133 +                    return PEP_OUT_OF_MEMORY;
   1.134 +                }
   1.135 +                identity->fpr_size = strlen(identity->fpr);
   1.136              }
   1.137 -            identity->fpr_size = strlen(identity->fpr);
   1.138 +            free_stringlist(keylist);
   1.139          }
   1.140 -        
   1.141      }
   1.142      
   1.143      // TODO : Check key for revoked state
   1.144      
   1.145      if (EMPTYSTR(identity->fpr) /* or revoked */)
   1.146      {
   1.147 +        stringlist_t *keylist = NULL;
   1.148          
   1.149          DEBUG_LOG("generating key pair", "debug", identity->address);
   1.150          status = generate_keypair(session, identity);
   1.151 @@ -353,8 +398,19 @@
   1.152              return PEP_OUT_OF_MEMORY;
   1.153          
   1.154          assert(keylist && keylist->value);
   1.155 -        if (keylist == NULL || keylist->value == NULL) {
   1.156 +        if (keylist == NULL) {
   1.157              return PEP_UNKNOWN_ERROR;
   1.158 +        }else if (keylist->value == NULL) {
   1.159 +            free_stringlist(keylist);
   1.160 +            return PEP_UNKNOWN_ERROR;
   1.161 +        }
   1.162 +        
   1.163 +        // Consider generated keys as own keys.
   1.164 +        status = own_key_add(session, identity->fpr);
   1.165 +        assert(status == PEP_STATUS_OK);
   1.166 +        if (status != PEP_STATUS_OK) {
   1.167 +            free_stringlist(keylist);
   1.168 +            return status;
   1.169          }
   1.170      }
   1.171      else
   1.172 @@ -363,7 +419,7 @@
   1.173          status = key_expired(session, identity->fpr, &expired);
   1.174          assert(status == PEP_STATUS_OK);
   1.175          if (status != PEP_STATUS_OK) {
   1.176 -            goto free_keylist;
   1.177 +            return status;
   1.178          }
   1.179  
   1.180          if (status == PEP_STATUS_OK && expired) {
   1.181 @@ -376,14 +432,11 @@
   1.182      status = set_identity(session, identity);
   1.183      assert(status == PEP_STATUS_OK);
   1.184      if (status != PEP_STATUS_OK) {
   1.185 -        goto free_keylist;
   1.186 +        return status;
   1.187      }
   1.188  
   1.189      return PEP_STATUS_OK;
   1.190  
   1.191 -free_keylist:
   1.192 -    free_stringlist(keylist);
   1.193 -    return status;
   1.194  }
   1.195  
   1.196  DYNAMIC_API PEP_STATUS register_examine_function(
     2.1 --- a/src/pEpEngine.c	Tue May 10 12:28:40 2016 +0200
     2.2 +++ b/src/pEpEngine.c	Tue May 10 13:48:01 2016 +0200
     2.3 @@ -177,7 +177,7 @@
     2.4                  "create table if not exists own_keys (\n"
     2.5                  "   fpr text primary key\n"
     2.6                  "       references pgp_keypair (fpr)\n"
     2.7 -                "       on delete cascade,\n"
     2.8 +                "       on delete cascade\n"
     2.9                  ");\n"
    2.10                  ,
    2.11              NULL,