ENGINE-152 ENGINE-153 ENGINE-74 ENGINE-118: merged into default.
authorKrista Grothoff <krista@pep-project.org>
Tue, 20 Dec 2016 11:24:15 +0100
changeset 15006cc35643fed0
parent 1496 eacf1934b6cc
parent 1499 e841d7759915
child 1503 0f86dbd30df1
ENGINE-152 ENGINE-153 ENGINE-74 ENGINE-118: merged into default.
     1.1 --- a/src/bloblist.c	Mon Dec 19 08:36:53 2016 +0100
     1.2 +++ b/src/bloblist.c	Tue Dec 20 11:24:15 2016 +0100
     1.3 @@ -165,16 +165,3 @@
     1.4  
     1.5      return len;
     1.6  }
     1.7 -
     1.8 -bloblist_t* consume_bloblist_head(bloblist_t *bloblist_head) {
     1.9 -    if (!bloblist_head)
    1.10 -        return NULL;
    1.11 -
    1.12 -    bloblist_t* next = bloblist_head->next;
    1.13 -
    1.14 -    free(bloblist_head->mime_type);
    1.15 -    free(bloblist_head->filename);
    1.16 -    free(bloblist_head);
    1.17 -
    1.18 -    return next;
    1.19 -}
     2.1 --- a/src/bloblist.h	Mon Dec 19 08:36:53 2016 +0100
     2.2 +++ b/src/bloblist.h	Tue Dec 20 11:24:15 2016 +0100
     2.3 @@ -91,18 +91,6 @@
     2.4  
     2.5  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
     2.6  
     2.7 -// consume_bloblist_head() - internal function to delete head of the bloblist
     2.8 -//
     2.9 -//  parameters:
    2.10 -//      bloblist (in)   bloblist to delete head from
    2.11 -//
    2.12 -//  return value:
    2.13 -//      new head of the bloblist 
    2.14 -//
    2.15 -
    2.16 -bloblist_t* consume_bloblist_head(bloblist_t *bloblist_head);
    2.17 -
    2.18 -
    2.19  #ifdef __cplusplus
    2.20  }
    2.21  #endif
     3.1 --- a/src/message_api.c	Mon Dec 19 08:36:53 2016 +0100
     3.2 +++ b/src/message_api.c	Tue Dec 20 11:24:15 2016 +0100
     3.3 @@ -1432,6 +1432,68 @@
     3.4      return PEP_STATUS_OK;
     3.5  }
     3.6  
     3.7 +PEP_STATUS combine_keylists(PEP_SESSION session, stringlist_t** verify_in, 
     3.8 +                            stringlist_t** keylist_in_out, 
     3.9 +                            pEp_identity* from) {
    3.10 +    
    3.11 +    if (!verify_in || !(*verify_in)) // this isn't really a problem.
    3.12 +        return PEP_STATUS_OK;
    3.13 +    
    3.14 +    stringlist_t* orig_verify = *verify_in;
    3.15 +    
    3.16 +    stringlist_t* verify_curr;
    3.17 +    stringlist_t* from_keys;
    3.18 +    
    3.19 +    /* FIXME: what to do if head needs to be null */
    3.20 +    PEP_STATUS status = find_keys(session, from->address, &from_keys);
    3.21 +    
    3.22 +    stringlist_t* from_fpr_node = NULL;
    3.23 +    stringlist_t* from_curr;
    3.24 +    
    3.25 +    for (from_curr = from_keys; from_curr; from_curr = from_curr->next) {
    3.26 +        for (verify_curr = orig_verify; verify_curr; verify_curr = verify_curr->next) {
    3.27 +            if (from_curr->value && verify_curr->value &&
    3.28 +                strcasecmp(from_curr->value, verify_curr->value) == 0) {
    3.29 +                from_fpr_node = from_curr;
    3.30 +                break;
    3.31 +            }
    3.32 +        }
    3.33 +    }
    3.34 +    
    3.35 +    if (!from_fpr_node) {
    3.36 +        status = PEP_KEY_NOT_FOUND;
    3.37 +        goto free;
    3.38 +    }
    3.39 +
    3.40 +    verify_curr = orig_verify;
    3.41 +    
    3.42 +    /* put "from" signer at the beginning of the list */
    3.43 +    if (strcasecmp(orig_verify->value, from_fpr_node->value) != 0) {
    3.44 +        orig_verify = stringlist_delete(orig_verify, from_fpr_node->value);
    3.45 +        verify_curr = new_stringlist(from_fpr_node->value);
    3.46 +        verify_curr->next = orig_verify;
    3.47 +    }
    3.48 +
    3.49 +    /* append keylist to signers */
    3.50 +    if (keylist_in_out && *keylist_in_out && (*keylist_in_out)->value) {
    3.51 +        stringlist_t** tail_pp = &verify_curr->next;
    3.52 +        
    3.53 +        while (*tail_pp) {
    3.54 +            tail_pp = &((*tail_pp)->next);
    3.55 +        }
    3.56 +        *tail_pp = *keylist_in_out;
    3.57 +    }
    3.58 +    
    3.59 +    *keylist_in_out = verify_curr;
    3.60 +    
    3.61 +    status = PEP_STATUS_OK;
    3.62 +    
    3.63 +free:
    3.64 +    free_stringlist(from_keys);
    3.65 +    return status;    
    3.66 +}
    3.67 +
    3.68 +
    3.69  DYNAMIC_API PEP_STATUS _decrypt_message(
    3.70          PEP_SESSION session,
    3.71          message *src,
    3.72 @@ -1472,36 +1534,6 @@
    3.73      if(status != PEP_STATUS_OK)
    3.74          return status;
    3.75  
    3.76 -    // IF longmsg and longmsg_formatted are empty, we MAY have an encrypted body
    3.77 -    // that's an attachment instead.
    3.78 -    // Check for encryption stuck in the first 2 attachments instead of the body
    3.79 -    // (RFC3156)
    3.80 -    //
    3.81 -    // if (!src->longmsg && !src->longmsg_formatted) {
    3.82 -    //     bloblist_t* attached_head = src->attachments;
    3.83 -    //     if (attached_head && 
    3.84 -    //         strcasecmp(attached_head->mime_type, "application/pgp-encrypted") == 0) {
    3.85 -    //         bloblist_t* enc_att_txt = attached_head->next;
    3.86 -    //         if (enc_att_txt && 
    3.87 -    //             strcasecmp(enc_att_txt->mime_type, "application/octet-stream") == 0) {
    3.88 -    //             size_t enc_att_len = enc_att_txt->size;
    3.89 -    //             char* newlongmsg = calloc(1, enc_att_len + 1);
    3.90 -    //             if (newlongmsg == NULL)
    3.91 -    //                 goto enomem;
    3.92 -    // 
    3.93 -    //             memcpy(newlongmsg, enc_att_txt, enc_att_len);
    3.94 -    //             newlongmsg[enc_att_len] = '\0';
    3.95 -    // 
    3.96 -    //             src->longmsg = newlongmsg;
    3.97 -    // 
    3.98 -    //             // delete attachments here
    3.99 -    //             src->attachments = enc_att_txt->next;
   3.100 -    //             consume_bloblist_head(attached_head);
   3.101 -    //             consume_bloblist_head(attached_head);
   3.102 -    //         }
   3.103 -    //     }
   3.104 -    // }
   3.105 -
   3.106      // Get detached signature, if any
   3.107      bloblist_t* detached_sig = NULL;
   3.108      char* dsig_text = NULL;
   3.109 @@ -1537,6 +1569,36 @@
   3.110                      return status;
   3.111                  }
   3.112              }
   3.113 +            
   3.114 +            char* slong = src->longmsg;
   3.115 +            char* sform = src->longmsg_formatted;
   3.116 +            bloblist_t* satt = src->attachments;
   3.117 +                                    
   3.118 +            if ((!slong || slong[0] == '\0')
   3.119 +                 && (!sform || sform[0] == '\0')) {
   3.120 +                if (satt) {
   3.121 +                    const char* inner_mime_type = satt->mime_type;
   3.122 +                    if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.123 +                        free(slong); /* in case of "" */
   3.124 +                        src->longmsg = strdup(satt->value);
   3.125 +                    
   3.126 +                        bloblist_t* next_node = satt->next;
   3.127 +                        if (next_node) {
   3.128 +                            inner_mime_type = next_node->mime_type;
   3.129 +                            if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.130 +                                free(sform);
   3.131 +                                src->longmsg_formatted = strdup(next_node->value);
   3.132 +                            }
   3.133 +                        }
   3.134 +                    }
   3.135 +                    else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.136 +                        free(sform);
   3.137 +                        src->longmsg_formatted = strdup(satt->value);
   3.138 +                    }                    
   3.139 +                }
   3.140 +            }       
   3.141 +
   3.142 +            
   3.143              return PEP_UNENCRYPTED;
   3.144  
   3.145          case PEP_enc_PGP_MIME:
   3.146 @@ -1576,27 +1638,63 @@
   3.147              case PEP_enc_PGP_MIME:
   3.148                  status = mime_decode_message(ptext, psize, &msg);
   3.149                  if (status != PEP_STATUS_OK)
   3.150 -                    goto pep_error;
   3.151 -                status = _get_detached_signature(msg, &detached_sig);
   3.152 -                if (decrypt_status == PEP_DECRYPTED && detached_sig) {
   3.153 -                    dsig_text = detached_sig->value;
   3.154 -                    dsig_size = detached_sig->size;
   3.155 -                    size_t ssize = 0;
   3.156 -                    char* stext = NULL;
   3.157 +                    goto pep_error;                
   3.158 +                
   3.159 +                char* mlong = msg->longmsg;
   3.160 +                char* mform = msg->longmsg_formatted;
   3.161 +                bloblist_t* matt = msg->attachments;
   3.162 +                                        
   3.163 +                if ((!mlong || mlong[0] == '\0')
   3.164 +                     && (!mform || mform[0] == '\0')) {
   3.165 +                    if (matt) {
   3.166 +                        const char* inner_mime_type = matt->mime_type;
   3.167 +                        if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.168 +                            free(mlong); /* in case of "" */
   3.169 +                            msg->longmsg = strdup(matt->value);
   3.170 +                        
   3.171 +                            bloblist_t* next_node = matt->next;
   3.172 +                            if (next_node) {
   3.173 +                                inner_mime_type = next_node->mime_type;
   3.174 +                                if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.175 +                                    free(mform);
   3.176 +                                    msg->longmsg_formatted = strdup(next_node->value);
   3.177 +                                }
   3.178 +                            }
   3.179 +                        }
   3.180 +                        else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.181 +                            free(mform);
   3.182 +                            msg->longmsg_formatted = strdup(matt->value);
   3.183 +                        }                    
   3.184 +                    }
   3.185 +                    if (msg->shortmsg) {
   3.186 +                        free(src->shortmsg);
   3.187 +                        src->shortmsg = strdup(msg->shortmsg);
   3.188 +                    }
   3.189 +                }    
   3.190  
   3.191 -                    status = _get_signed_text(ptext, psize, &stext, &ssize);
   3.192 -                    stringlist_t *_verify_keylist = NULL;
   3.193 +                if (decrypt_status != PEP_DECRYPTED_AND_VERIFIED) {
   3.194 +                    status = _get_detached_signature(msg, &detached_sig);
   3.195 +                    if (decrypt_status == PEP_DECRYPTED && detached_sig) {
   3.196 +                        dsig_text = detached_sig->value;
   3.197 +                        dsig_size = detached_sig->size;
   3.198 +                        size_t ssize = 0;
   3.199 +                        char* stext = NULL;
   3.200  
   3.201 -                    if (ssize > 0 && stext) {
   3.202 -                        status = cryptotech[crypto].verify_text(session, stext,
   3.203 -                                                                ssize, dsig_text, dsig_size,
   3.204 -                                                                &_verify_keylist);
   3.205 +                        status = _get_signed_text(ptext, psize, &stext, &ssize);
   3.206 +                        stringlist_t *_verify_keylist = NULL;
   3.207  
   3.208 -                        if (status == PEP_VERIFIED || status == PEP_VERIFIED_AND_TRUSTED)
   3.209 -                            decrypt_status = PEP_DECRYPTED_AND_VERIFIED;
   3.210 +                        if (ssize > 0 && stext) {
   3.211 +                            status = cryptotech[crypto].verify_text(session, stext,
   3.212 +                                                                    ssize, dsig_text, dsig_size,
   3.213 +                                                                    &_verify_keylist);
   3.214 +
   3.215 +                            if (status == PEP_VERIFIED || status == PEP_VERIFIED_AND_TRUSTED)
   3.216 +                                decrypt_status = PEP_DECRYPTED_AND_VERIFIED;
   3.217 +                            
   3.218 +                                status = combine_keylists(session, &_verify_keylist, &_keylist, src->from);
   3.219 +                        }
   3.220                      }
   3.221                  }
   3.222 -
   3.223                  break;
   3.224  
   3.225              case PEP_enc_pieces:
   3.226 @@ -1633,7 +1731,7 @@
   3.227                          status = decrypt_and_verify(session, attctext, attcsize,
   3.228                                                      NULL, 0,
   3.229                                                      &ptext, &psize, &_keylist);
   3.230 -                        free_stringlist(_keylist);
   3.231 +                        free_stringlist(_keylist); // FIXME: Why do we do this?
   3.232  
   3.233                          if (ptext) {
   3.234                              if (is_encrypted_html_attachment(_s)) {
   3.235 @@ -1719,10 +1817,9 @@
   3.236                          goto enomem;
   3.237                  }
   3.238                  break;
   3.239 -
   3.240              default:
   3.241 -                // BUG: must implement more
   3.242 -                NOT_IMPLEMENTED
   3.243 +                    // BUG: must implement more
   3.244 +                    NOT_IMPLEMENTED
   3.245          }
   3.246  
   3.247          // check for private key in decrypted message attachement while inporting