NETPGP-18 adding recipients fpr/key_id to pgp_decrypt_and_verify returned keylist NETPGP-18
authorEdouard Tisserant <edouard@pep-project.org>
Fri, 24 Mar 2017 02:51:45 +0100
branchNETPGP-18
changeset 1694032e59ccdd93
parent 1693 7cbc1b22a250
child 1695 4f4aae28570f
NETPGP-18 adding recipients fpr/key_id to pgp_decrypt_and_verify returned keylist
src/pgp_netpgp.c
src/stringlist.c
src/stringlist.h
     1.1 --- a/src/pgp_netpgp.c	Tue Mar 21 11:18:34 2017 +0100
     1.2 +++ b/src/pgp_netpgp.c	Fri Mar 24 02:51:45 2017 +0100
     1.3 @@ -273,12 +273,14 @@
     1.4  static PEP_STATUS _validation_results(
     1.5          netpgp_t *netpgp,
     1.6          pgp_validation_t *vresult,
     1.7 -        stringlist_t **_keylist
     1.8 +        stringlist_t **keylist
     1.9      )
    1.10  {
    1.11      time_t    now;
    1.12      time_t    t;
    1.13  
    1.14 +    *keylist = NULL;
    1.15 +
    1.16      now = time(NULL);
    1.17      if (now < vresult->birthtime) {
    1.18          // signature is not valid yet
    1.19 @@ -292,14 +294,17 @@
    1.20      if (vresult->validc && vresult->valid_sigs &&
    1.21          !vresult->invalidc && !vresult->unknownc ) {
    1.22          
    1.23 +        stringlist_t *_keylist;
    1.24 +
    1.25          // caller responsible to free
    1.26 -        *_keylist = new_stringlist(NULL);
    1.27 -        assert(*_keylist);
    1.28 -        if (*_keylist == NULL) {
    1.29 +        _keylist = new_stringlist(NULL);
    1.30 +        assert(_keylist);
    1.31 +        if (_keylist == NULL) {
    1.32              return PEP_OUT_OF_MEMORY;
    1.33          }
    1.34          
    1.35 -        stringlist_t *k = *_keylist;
    1.36 +        stringlist_t *k = _keylist;
    1.37 +        unsigned c = 0;
    1.38          for (unsigned n = 0; n < vresult->validc; ++n) {
    1.39              unsigned from = 0;
    1.40              const pgp_key_t	 *signer;
    1.41 @@ -315,21 +320,31 @@
    1.42                             signer->pubkeyfpr.fingerprint,
    1.43                             signer->pubkeyfpr.length);
    1.44              else
    1.45 -                return PEP_VERIFY_NO_KEY;
    1.46 +                continue;
    1.47  
    1.48 -            if (fprstr == NULL)
    1.49 +            if (fprstr == NULL){
    1.50 +                free_stringlist(_keylist);
    1.51                  return PEP_OUT_OF_MEMORY;
    1.52 +            }
    1.53  
    1.54              k = stringlist_add(k, fprstr);
    1.55  
    1.56              free(fprstr);
    1.57  
    1.58              if(!k){
    1.59 -                free_stringlist(*_keylist);
    1.60 +                free_stringlist(_keylist);
    1.61                  return PEP_OUT_OF_MEMORY;
    1.62              }
    1.63 +
    1.64 +            c++;
    1.65          }
    1.66 -        return PEP_STATUS_OK;
    1.67 +        if(c > 0) {
    1.68 +            *keylist = _keylist;
    1.69 +            return PEP_STATUS_OK;
    1.70 +        }
    1.71 +
    1.72 +        free_stringlist(_keylist);
    1.73 +        return PEP_VERIFY_NO_KEY;
    1.74      }
    1.75      if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
    1.76          // No signatures found - is this memory signed?
    1.77 @@ -379,11 +394,14 @@
    1.78      pgp_validation_t *vresult = malloc(sizeof(pgp_validation_t));
    1.79      memset(vresult, 0x0, sizeof(pgp_validation_t));
    1.80  
    1.81 +    key_id_t *recipients_key_ids = NULL;
    1.82 +    unsigned recipients_count = 0;
    1.83 +
    1.84      pgp_memory_t *mem = pgp_decrypt_and_validate_buf(netpgp.io, vresult, ctext, csize,
    1.85                  netpgp.secring, netpgp.pubring,
    1.86                  _armoured(ctext, csize, ARMOR_HEAD),
    1.87 -                0 /* sshkeys */,
    1.88 -                NULL, -1, NULL  /* pass fp,attempts,cb */);
    1.89 +                 &recipients_key_ids, &recipients_count);
    1.90 +
    1.91      if (mem == NULL) {
    1.92          result = PEP_OUT_OF_MEMORY;
    1.93          goto unlock_netpgp;
    1.94 @@ -405,9 +423,12 @@
    1.95  
    1.96      if (result == PEP_DECRYPTED) {
    1.97          result = _validation_results(&netpgp, vresult, &_keylist);
    1.98 -        if (result == PEP_DECRYPTED) {
    1.99 -            //no change
   1.100 -        } else if (result == PEP_VERIFY_NO_KEY) {
   1.101 +        if (result == PEP_DECRYPTED ||
   1.102 +            result == PEP_VERIFY_NO_KEY) {
   1.103 +            if(stringlist_add(_keylist, "") == NULL) {
   1.104 +                result = PEP_OUT_OF_MEMORY;
   1.105 +                goto free_keylist;
   1.106 +            }
   1.107              result = PEP_DECRYPTED;
   1.108          }else if (result != PEP_STATUS_OK) {
   1.109              goto free_ptext;
   1.110 @@ -416,6 +437,41 @@
   1.111          }
   1.112      }
   1.113  
   1.114 +    stringlist_t *k = _keylist;
   1.115 +    for (unsigned n = 0; n < recipients_count; ++n) {
   1.116 +        unsigned from = 0;
   1.117 +        const pgp_key_t	 *rcpt;
   1.118 +        char *fprstr = NULL;
   1.119 +        key_id_t *keyid = &recipients_key_ids[n];
   1.120 +
   1.121 +        rcpt = pgp_getkeybyid(netpgp.io, netpgp.pubring,
   1.122 +                                *keyid, &from, NULL, NULL,
   1.123 +                                0, 0); /* check neither revocation nor expiry*/
   1.124 +        if(rcpt)
   1.125 +            fpr_to_str(&fprstr,
   1.126 +                       rcpt->pubkeyfpr.fingerprint,
   1.127 +                       rcpt->pubkeyfpr.length);
   1.128 +        else
   1.129 +            // if no key found put ID instead of fpr
   1.130 +            fpr_to_str(&fprstr,
   1.131 +                       *keyid,
   1.132 +                       sizeof(key_id_t));
   1.133 +
   1.134 +        if (fprstr == NULL){
   1.135 +            free_stringlist(_keylist);
   1.136 +            return PEP_OUT_OF_MEMORY;
   1.137 +        }
   1.138 +
   1.139 +        k = stringlist_add_unique(k, fprstr);
   1.140 +
   1.141 +        free(fprstr);
   1.142 +
   1.143 +        if(!k){
   1.144 +            free_stringlist(_keylist);
   1.145 +            return PEP_OUT_OF_MEMORY;
   1.146 +        }
   1.147 +    }
   1.148 +
   1.149      if (result == PEP_DECRYPTED_AND_VERIFIED
   1.150          || result == PEP_DECRYPTED) {
   1.151          *ptext = _ptext;
   1.152 @@ -429,6 +485,7 @@
   1.153          goto free_pgp;
   1.154      }
   1.155  
   1.156 +free_keylist:
   1.157      free_stringlist(_keylist);
   1.158  
   1.159  free_ptext:
     2.1 --- a/src/stringlist.c	Tue Mar 21 11:18:34 2017 +0100
     2.2 +++ b/src/stringlist.c	Fri Mar 24 02:51:45 2017 +0100
     2.3 @@ -53,6 +53,39 @@
     2.4      return dst;
     2.5  }
     2.6  
     2.7 +static bool _stringlist_add_first(
     2.8 +        stringlist_t *stringlist,
     2.9 +        stringlist_t **result,
    2.10 +        const char *value
    2.11 +    )
    2.12 +{  
    2.13 +    // empty list (no nodes)
    2.14 +    if (stringlist == NULL) {
    2.15 +        *result = new_stringlist(value);
    2.16 +        return true;
    2.17 +    }
    2.18 +
    2.19 +    // empty list (one node, no value)
    2.20 +    if (stringlist->value == NULL) {
    2.21 +        if (stringlist->next) {
    2.22 +            *result = NULL; // invalid list
    2.23 +            return true;
    2.24 +        } 
    2.25 +            
    2.26 +        stringlist->value = strdup(value);
    2.27 +        assert(stringlist->value);
    2.28 +        
    2.29 +        if (stringlist->value == NULL) {
    2.30 +            *result = NULL;
    2.31 +            return true;
    2.32 +        }
    2.33 +        
    2.34 +        *result = stringlist;
    2.35 +        return true;
    2.36 +    }
    2.37 +    return false;
    2.38 +}
    2.39 +
    2.40  DYNAMIC_API stringlist_t *stringlist_add(
    2.41          stringlist_t *stringlist,
    2.42          const char *value
    2.43 @@ -62,23 +95,9 @@
    2.44      if (value == NULL)
    2.45          return NULL;
    2.46  
    2.47 -    // empty list (no nodes)
    2.48 -    if (stringlist == NULL)
    2.49 -        return new_stringlist(value);
    2.50 -
    2.51 -    // empty list (one node, no value)
    2.52 -    if (stringlist->value == NULL) {
    2.53 -        if (stringlist->next) 
    2.54 -            return NULL; // invalid list
    2.55 -            
    2.56 -        stringlist->value = strdup(value);
    2.57 -        assert(stringlist->value);
    2.58 -        
    2.59 -        if (stringlist->value == NULL)
    2.60 -            return NULL;
    2.61 -        
    2.62 -        return stringlist;
    2.63 -    }
    2.64 +    stringlist_t *result = NULL;
    2.65 +    if(_stringlist_add_first(stringlist, &result, value))
    2.66 +        return result;
    2.67      
    2.68      stringlist_t* list_curr = stringlist;
    2.69  
    2.70 @@ -94,6 +113,42 @@
    2.71      return list_curr->next;
    2.72  }
    2.73  
    2.74 +DYNAMIC_API stringlist_t *stringlist_add_unique(
    2.75 +        stringlist_t *stringlist,
    2.76 +        const char *value
    2.77 +    )
    2.78 +{  
    2.79 +    assert(value);
    2.80 +    if (value == NULL)
    2.81 +        return NULL;
    2.82 +
    2.83 +    stringlist_t *result = NULL;
    2.84 +    if(_stringlist_add_first(stringlist, &result, value))
    2.85 +        return result;
    2.86 +    
    2.87 +    stringlist_t* list_curr = stringlist;
    2.88 +
    2.89 +    bool found = false;
    2.90 +    while (list_curr->next) {
    2.91 +        if(strcmp(list_curr->value,value)==0)
    2.92 +            found = true;
    2.93 +        list_curr = list_curr->next;
    2.94 +    }
    2.95 +     
    2.96 +    if (!found) {
    2.97 +        list_curr->next = new_stringlist(value);
    2.98 +
    2.99 +        assert(list_curr->next);
   2.100 +        if (list_curr->next == NULL)
   2.101 +            return NULL;
   2.102 +
   2.103 +        return list_curr->next;
   2.104 +    } else {
   2.105 +        return list_curr;
   2.106 +    }
   2.107 +}
   2.108 +
   2.109 +
   2.110  DYNAMIC_API stringlist_t *stringlist_append(
   2.111          stringlist_t *stringlist,
   2.112          stringlist_t *second
     3.1 --- a/src/stringlist.h	Tue Mar 21 11:18:34 2017 +0100
     3.2 +++ b/src/stringlist.h	Fri Mar 24 02:51:45 2017 +0100
     3.3 @@ -61,6 +61,24 @@
     3.4          const char *value
     3.5      );
     3.6  
     3.7 +// stringlist_add_unique() - add string to stringlist, if not already there
     3.8 +//
     3.9 +//  parameters:
    3.10 +//      stringlist (in)     stringlist struct or NULL to create a new one
    3.11 +//      value (in)          value as C string
    3.12 +//
    3.13 +//  return value:
    3.14 +//      pointer to last element in stringlist or NULL if out of memory
    3.15 +//
    3.16 +//  caveat:
    3.17 +//      the value is being copied before being added to the list
    3.18 +//      the original string is still being owned by the caller
    3.19 +
    3.20 +DYNAMIC_API stringlist_t *stringlist_add_unique(
    3.21 +        stringlist_t *stringlist,
    3.22 +        const char *value
    3.23 +    );
    3.24 +
    3.25  
    3.26  // stringlist_append() - append stringlist to stringlist
    3.27  //