merged in default fdik_sync
authorKrista Bennett <krista@pep-project.org>
Sat, 25 Mar 2017 11:30:41 +0100
branchfdik_sync
changeset 17008c1c85bf631a
parent 1699 6fb3820c4f77
parent 1697 2fd0761a707d
merged in default
src/pgp_netpgp.c
     1.1 --- a/src/pgp_netpgp.c	Sat Mar 25 11:28:29 2017 +0100
     1.2 +++ b/src/pgp_netpgp.c	Sat Mar 25 11:30:41 2017 +0100
     1.3 @@ -227,7 +227,7 @@
     1.4          return 0;
     1.5  
     1.6      for (n = 0, i = 0 ; i < length; i += 2) {
     1.7 -        n += snprintf(&((*str)[n]), 5, "%02x%02x", fpr[i], fpr[i+1]);
     1.8 +        n += snprintf(&((*str)[n]), 5, "%02X%02X", fpr[i], fpr[i+1]);
     1.9      }
    1.10  
    1.11      return 1;
    1.12 @@ -273,12 +273,14 @@
    1.13  static PEP_STATUS _validation_results(
    1.14          netpgp_t *netpgp,
    1.15          pgp_validation_t *vresult,
    1.16 -        stringlist_t **_keylist
    1.17 +        stringlist_t **keylist
    1.18      )
    1.19  {
    1.20      time_t    now;
    1.21      time_t    t;
    1.22  
    1.23 +    *keylist = NULL;
    1.24 +
    1.25      now = time(NULL);
    1.26      if (now < vresult->birthtime) {
    1.27          // signature is not valid yet
    1.28 @@ -292,14 +294,17 @@
    1.29      if (vresult->validc && vresult->valid_sigs &&
    1.30          !vresult->invalidc && !vresult->unknownc ) {
    1.31          
    1.32 +        stringlist_t *_keylist;
    1.33 +
    1.34          // caller responsible to free
    1.35 -        *_keylist = new_stringlist(NULL);
    1.36 -        assert(*_keylist);
    1.37 -        if (*_keylist == NULL) {
    1.38 +        _keylist = new_stringlist(NULL);
    1.39 +        assert(_keylist);
    1.40 +        if (_keylist == NULL) {
    1.41              return PEP_OUT_OF_MEMORY;
    1.42          }
    1.43          
    1.44 -        stringlist_t *k = *_keylist;
    1.45 +        stringlist_t *k = _keylist;
    1.46 +        unsigned c = 0;
    1.47          for (unsigned n = 0; n < vresult->validc; ++n) {
    1.48              unsigned from = 0;
    1.49              const pgp_key_t	 *signer;
    1.50 @@ -315,21 +320,31 @@
    1.51                             signer->pubkeyfpr.fingerprint,
    1.52                             signer->pubkeyfpr.length);
    1.53              else
    1.54 -                return PEP_VERIFY_NO_KEY;
    1.55 +                continue;
    1.56  
    1.57 -            if (fprstr == NULL)
    1.58 +            if (fprstr == NULL){
    1.59 +                free_stringlist(_keylist);
    1.60                  return PEP_OUT_OF_MEMORY;
    1.61 +            }
    1.62  
    1.63              k = stringlist_add(k, fprstr);
    1.64  
    1.65              free(fprstr);
    1.66  
    1.67              if(!k){
    1.68 -                free_stringlist(*_keylist);
    1.69 +                free_stringlist(_keylist);
    1.70                  return PEP_OUT_OF_MEMORY;
    1.71              }
    1.72 +
    1.73 +            c++;
    1.74          }
    1.75 -        return PEP_STATUS_OK;
    1.76 +        if(c > 0) {
    1.77 +            *keylist = _keylist;
    1.78 +            return PEP_STATUS_OK;
    1.79 +        }
    1.80 +
    1.81 +        free_stringlist(_keylist);
    1.82 +        return PEP_VERIFY_NO_KEY;
    1.83      }
    1.84      if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
    1.85          // No signatures found - is this memory signed?
    1.86 @@ -379,11 +394,14 @@
    1.87      pgp_validation_t *vresult = malloc(sizeof(pgp_validation_t));
    1.88      memset(vresult, 0x0, sizeof(pgp_validation_t));
    1.89  
    1.90 +    key_id_t *recipients_key_ids = NULL;
    1.91 +    unsigned recipients_count = 0;
    1.92 +
    1.93      pgp_memory_t *mem = pgp_decrypt_and_validate_buf(netpgp.io, vresult, ctext, csize,
    1.94                  netpgp.secring, netpgp.pubring,
    1.95                  _armoured(ctext, csize, ARMOR_HEAD),
    1.96 -                0 /* sshkeys */,
    1.97 -                NULL, -1, NULL  /* pass fp,attempts,cb */);
    1.98 +                 &recipients_key_ids, &recipients_count);
    1.99 +
   1.100      if (mem == NULL) {
   1.101          result = PEP_OUT_OF_MEMORY;
   1.102          goto unlock_netpgp;
   1.103 @@ -405,9 +423,12 @@
   1.104  
   1.105      if (result == PEP_DECRYPTED) {
   1.106          result = _validation_results(&netpgp, vresult, &_keylist);
   1.107 -        if (result == PEP_DECRYPTED) {
   1.108 -            //no change
   1.109 -        } else if (result == PEP_VERIFY_NO_KEY) {
   1.110 +        if (result == PEP_DECRYPTED ||
   1.111 +            result == PEP_VERIFY_NO_KEY) {
   1.112 +            if((_keylist = new_stringlist("")) == NULL) {
   1.113 +                result = PEP_OUT_OF_MEMORY;
   1.114 +                goto free_ptext;
   1.115 +            }
   1.116              result = PEP_DECRYPTED;
   1.117          }else if (result != PEP_STATUS_OK) {
   1.118              goto free_ptext;
   1.119 @@ -416,19 +437,53 @@
   1.120          }
   1.121      }
   1.122  
   1.123 +    stringlist_t *k = _keylist;
   1.124 +    for (unsigned n = 0; n < recipients_count; ++n) {
   1.125 +        unsigned from = 0;
   1.126 +        const pgp_key_t	 *rcpt;
   1.127 +        char *fprstr = NULL;
   1.128 +        key_id_t *keyid = &recipients_key_ids[n];
   1.129 +
   1.130 +        rcpt = pgp_getkeybyid(netpgp.io, netpgp.pubring,
   1.131 +                                *keyid, &from, NULL, NULL,
   1.132 +                                0, 0); /* check neither revocation nor expiry*/
   1.133 +        if(rcpt)
   1.134 +            fpr_to_str(&fprstr,
   1.135 +                       rcpt->pubkeyfpr.fingerprint,
   1.136 +                       rcpt->pubkeyfpr.length);
   1.137 +        else
   1.138 +            // if no key found put ID instead of fpr
   1.139 +            fpr_to_str(&fprstr,
   1.140 +                       *keyid,
   1.141 +                       sizeof(key_id_t));
   1.142 +
   1.143 +        if (fprstr == NULL){
   1.144 +            result = PEP_OUT_OF_MEMORY;
   1.145 +            goto free_keylist;
   1.146 +        }
   1.147 +
   1.148 +        k = stringlist_add_unique(k, fprstr);
   1.149 +
   1.150 +        free(fprstr);
   1.151 +
   1.152 +        if(!k){
   1.153 +            result = PEP_OUT_OF_MEMORY;
   1.154 +            goto free_keylist;
   1.155 +        }
   1.156 +    }
   1.157 +
   1.158      if (result == PEP_DECRYPTED_AND_VERIFIED
   1.159          || result == PEP_DECRYPTED) {
   1.160          *ptext = _ptext;
   1.161          *psize = _psize;
   1.162          (*ptext)[*psize] = 0; // safeguard for naive users
   1.163 -        if (result == PEP_DECRYPTED_AND_VERIFIED) {
   1.164 -            *keylist = _keylist;
   1.165 -        }
   1.166 +        *keylist = _keylist;
   1.167  
   1.168          /* _ptext and _keylist ownership transfer, don't free */
   1.169          goto free_pgp;
   1.170      }
   1.171  
   1.172 +free_keylist:
   1.173      free_stringlist(_keylist);
   1.174  
   1.175  free_ptext:
   1.176 @@ -534,14 +589,14 @@
   1.177      return result;
   1.178  }
   1.179  
   1.180 -PEP_STATUS pgp_encrypt_and_sign(
   1.181 +static PEP_STATUS _encrypt_and_sign(
   1.182      PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   1.183 -    size_t psize, char **ctext, size_t *csize
   1.184 +    size_t psize, char **ctext, size_t *csize, bool do_sign
   1.185      )
   1.186  {
   1.187      pgp_key_t *signer = NULL;
   1.188      pgp_seckey_t *seckey = NULL;
   1.189 -    pgp_memory_t *signedmem;
   1.190 +    pgp_memory_t *signedmem = NULL;
   1.191      pgp_memory_t *cmem;
   1.192      const char *hashalg;
   1.193      pgp_keyring_t *rcpts;
   1.194 @@ -629,25 +684,38 @@
   1.195  
   1.196      hashalg = netpgp_getvar(&netpgp, "hash");
   1.197  
   1.198 -    // Sign data
   1.199 -    signedmem = pgp_sign_buf(netpgp.io, ptext, psize, seckey,
   1.200 -                time(NULL), /* birthtime */
   1.201 -                0 /* duration */,
   1.202 -                hashalg,
   1.203 -                0 /* armored */,
   1.204 -                0 /* cleartext */);
   1.205 +    const char *stext;
   1.206 +    size_t ssize;
   1.207 +    unsigned encrypt_raw_packet;
   1.208 +   
   1.209 +    if (do_sign) {  
   1.210 +        // Sign data
   1.211 +        signedmem = pgp_sign_buf(netpgp.io, ptext, psize, seckey,
   1.212 +                    time(NULL), /* birthtime */
   1.213 +                    0 /* duration */,
   1.214 +                    hashalg,
   1.215 +                    0 /* armored */,
   1.216 +                    0 /* cleartext */);
   1.217  
   1.218 -    if (!signedmem) {
   1.219 -        result = PEP_UNENCRYPTED;
   1.220 -        goto free_rcpts;
   1.221 +        if (!signedmem) {
   1.222 +            result = PEP_UNENCRYPTED;
   1.223 +            goto free_rcpts;
   1.224 +        }
   1.225 +        stext = (char*) pgp_mem_data(signedmem);
   1.226 +        ssize = pgp_mem_len(signedmem);
   1.227 +        encrypt_raw_packet = 1 /* takes raw OpenPGP message */;
   1.228 +    } else {
   1.229 +        stext = ptext;
   1.230 +        ssize = psize;
   1.231 +        encrypt_raw_packet = 0 /* not a raw OpenPGP message */;
   1.232      }
   1.233  
   1.234 -    // Encrypt signed data
   1.235 +    // Encrypt (maybe) signed data
   1.236  
   1.237 -    cmem = pgp_encrypt_buf(netpgp.io, pgp_mem_data(signedmem),
   1.238 -            pgp_mem_len(signedmem), rcpts, 1 /* armored */,
   1.239 +    cmem = pgp_encrypt_buf(netpgp.io, stext,
   1.240 +            ssize, rcpts, 1 /* armored */,
   1.241              netpgp_getvar(&netpgp, "cipher"),
   1.242 -            1 /* takes raw OpenPGP message */);
   1.243 +            encrypt_raw_packet);
   1.244  
   1.245      if (cmem == NULL) {
   1.246          result = PEP_OUT_OF_MEMORY;
   1.247 @@ -676,7 +744,9 @@
   1.248  free_cmem :
   1.249      pgp_memory_free(cmem);
   1.250  free_signedmem :
   1.251 -    pgp_memory_free(signedmem);
   1.252 +    if (do_sign) {
   1.253 +        pgp_memory_free(signedmem);
   1.254 +    }
   1.255  free_rcpts :
   1.256      pgp_keyring_free(rcpts);
   1.257  unlock_netpgp:
   1.258 @@ -685,12 +755,26 @@
   1.259      return result;
   1.260  }
   1.261  
   1.262 +PEP_STATUS pgp_encrypt_and_sign(
   1.263 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   1.264 +    size_t psize, char **ctext, size_t *csize
   1.265 +    )
   1.266 +{
   1.267 +    PEP_STATUS result;
   1.268 +    result = _encrypt_and_sign(session, keylist, ptext, psize, ctext, csize,
   1.269 +                               true);
   1.270 +    return result;
   1.271 +}
   1.272 +
   1.273  PEP_STATUS pgp_encrypt_only(
   1.274          PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   1.275          size_t psize, char **ctext, size_t *csize
   1.276      )
   1.277  {
   1.278 -    return PEP_UNKNOWN_ERROR; // FIXME: Unimplemented!
   1.279 +    PEP_STATUS result;
   1.280 +    result = _encrypt_and_sign(session, keylist, ptext, psize, ctext, csize,
   1.281 +                               false);
   1.282 +    return result;
   1.283  }
   1.284  
   1.285  PEP_STATUS pgp_sign_text(
     2.1 --- a/src/stringlist.c	Sat Mar 25 11:28:29 2017 +0100
     2.2 +++ b/src/stringlist.c	Sat Mar 25 11:30:41 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	Sat Mar 25 11:28:29 2017 +0100
     3.2 +++ b/src/stringlist.h	Sat Mar 25 11:30:41 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  //