Made myself() re-use already selected fpr from pre-existing identity if not explicitely given. More restriction while selecting gpg ring's key should still be enforced.
authorEdouard Tisserant
Mon, 02 May 2016 01:50:58 +0200
changeset 56061966cd2d7a7
parent 559 32811e6a231c
child 561 9d8d5886494b
Made myself() re-use already selected fpr from pre-existing identity if not explicitely given. More restriction while selecting gpg ring's key should still be enforced.
src/keymanagement.c
     1.1 --- a/src/keymanagement.c	Sat Apr 30 17:59:16 2016 +0200
     1.2 +++ b/src/keymanagement.c	Mon May 02 01:50:58 2016 +0200
     1.3 @@ -267,6 +267,7 @@
     1.4  
     1.5  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
     1.6  {
     1.7 +    pEp_identity *stored_identity;
     1.8      PEP_STATUS status;
     1.9      stringlist_t *keylist = NULL;
    1.10  
    1.11 @@ -285,12 +286,69 @@
    1.12  
    1.13      DEBUG_LOG("myself", "debug", identity->address);
    1.14  
    1.15 -    status = find_keys(session, identity->address, &keylist);
    1.16 +    
    1.17 +    status = get_identity(session,
    1.18 +                          identity->address,
    1.19 +                          identity->user_id,
    1.20 +                          &stored_identity);
    1.21 +    
    1.22      assert(status != PEP_OUT_OF_MEMORY);
    1.23      if (status == PEP_OUT_OF_MEMORY)
    1.24          return PEP_OUT_OF_MEMORY;
    1.25 -
    1.26 -    if (keylist == NULL || keylist->value == NULL) {
    1.27 +    
    1.28 +    if (stored_identity)
    1.29 +    {
    1.30 +        if (EMPTYSTR(identity->fpr)) {
    1.31 +            identity->fpr = strndup(stored_identity->fpr, stored_identity->fpr_size);
    1.32 +            assert(identity->fpr);
    1.33 +            if (identity->fpr == NULL)
    1.34 +            {
    1.35 +                return PEP_OUT_OF_MEMORY;
    1.36 +            }
    1.37 +            identity->fpr_size = stored_identity->fpr_size;
    1.38 +        }
    1.39 +    }
    1.40 +    else
    1.41 +    {
    1.42 +        free(identity->fpr);
    1.43 +        identity->fpr_size = 0;
    1.44 +        
    1.45 +        status = find_keys(session, identity->address, &keylist);
    1.46 +        assert(status != PEP_OUT_OF_MEMORY);
    1.47 +        if (status == PEP_OUT_OF_MEMORY)
    1.48 +            return PEP_OUT_OF_MEMORY;
    1.49 +        
    1.50 +        if (keylist != NULL && keylist->value != NULL)
    1.51 +        {
    1.52 +            // BUG : Vulnerable to auto-key-import poisoning.
    1.53 +            //       Attacker's key with forged userId could have been
    1.54 +            //       auto imported from already received email and be used here
    1.55 +            
    1.56 +            // TODO : iterate over list to elect best key
    1.57 +            // TODO : discard keys which aren't private
    1.58 +            // TODO : discard keys which aren't either
    1.59 +            //             - own generated key
    1.60 +            //             - own from synchronized device group
    1.61 +            //             - already fully trusted as a public key of known
    1.62 +            //               identity, for that same address
    1.63 +            //               (case of imported key for mailing lists)
    1.64 +            
    1.65 +            identity->fpr = strdup(keylist->value);
    1.66 +            assert(identity->fpr);
    1.67 +            if (identity->fpr == NULL)
    1.68 +            {
    1.69 +                return PEP_OUT_OF_MEMORY;
    1.70 +            }
    1.71 +            identity->fpr_size = strlen(identity->fpr);
    1.72 +        }
    1.73 +        
    1.74 +    }
    1.75 +    
    1.76 +    // TODO : Check key for revoked state
    1.77 +    
    1.78 +    if (EMPTYSTR(identity->fpr) /* or revoked */)
    1.79 +    {
    1.80 +        
    1.81          DEBUG_LOG("generating key pair", "debug", identity->address);
    1.82          status = generate_keypair(session, identity);
    1.83          assert(status != PEP_OUT_OF_MEMORY);
    1.84 @@ -300,20 +358,21 @@
    1.85              DEBUG_LOG("generating key pair failed", "debug", buf);
    1.86              return status;
    1.87          }
    1.88 -
    1.89 +        
    1.90          status = find_keys(session, identity->address, &keylist);
    1.91          assert(status != PEP_OUT_OF_MEMORY);
    1.92          if (status == PEP_OUT_OF_MEMORY)
    1.93              return PEP_OUT_OF_MEMORY;
    1.94 -
    1.95 +        
    1.96          assert(keylist && keylist->value);
    1.97          if (keylist == NULL || keylist->value == NULL) {
    1.98              return PEP_UNKNOWN_ERROR;
    1.99          }
   1.100      }
   1.101 -    else {
   1.102 +    else
   1.103 +    {
   1.104          bool expired;
   1.105 -        status = key_expired(session, keylist->value, &expired);
   1.106 +        status = key_expired(session, identity->fpr, &expired);
   1.107          assert(status == PEP_STATUS_OK);
   1.108          if (status != PEP_STATUS_OK) {
   1.109              goto free_keylist;
   1.110 @@ -321,21 +380,11 @@
   1.111  
   1.112          if (status == PEP_STATUS_OK && expired) {
   1.113              timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
   1.114 -            renew_key(session, keylist->value, ts);
   1.115 +            renew_key(session, identity->fpr, ts);
   1.116              free_timestamp(ts);
   1.117          }
   1.118      }
   1.119  
   1.120 -    if (identity->fpr)
   1.121 -        free(identity->fpr);
   1.122 -    identity->fpr = strdup(keylist->value);
   1.123 -    assert(identity->fpr);
   1.124 -    if (identity->fpr == NULL){
   1.125 -        status = PEP_OUT_OF_MEMORY;
   1.126 -        goto free_keylist;
   1.127 -    }
   1.128 -    identity->fpr_size = strlen(identity->fpr);
   1.129 -
   1.130      status = set_identity(session, identity);
   1.131      assert(status == PEP_STATUS_OK);
   1.132      if (status != PEP_STATUS_OK) {