ENGINE-215: get_trustwords now uses xor'd fprs ENGINE-215
authorKrista Bennett <krista@pep-project.org>
Thu, 15 Jun 2017 18:44:07 +0200
branchENGINE-215
changeset 18649ce429048fd7
parent 1857 52e46f43ac67
child 1865 6e6773656dff
ENGINE-215: get_trustwords now uses xor'd fprs
src/message_api.c
src/pEpEngine.h
test/trustwords_test.cc
     1.1 --- a/src/message_api.c	Wed Jun 14 18:58:09 2017 +0200
     1.2 +++ b/src/message_api.c	Thu Jun 15 18:44:07 2017 +0200
     1.3 @@ -2328,6 +2328,43 @@
     1.4      return num_to_asciihex(xor_num);
     1.5  }
     1.6  
     1.7 +static char* skip_separators(char* current, char* begin) {
     1.8 +    while (current >= begin) {
     1.9 +        /* .:,;-_ ' ' - [2c-2e] [3a-3b] [20] [5f] */
    1.10 +        char check_char = *current;
    1.11 +        switch (check_char) {
    1.12 +            case '.':
    1.13 +            case ':':
    1.14 +            case ',':
    1.15 +            case ';':
    1.16 +            case '-':
    1.17 +            case '_':
    1.18 +            case ' ':
    1.19 +                current--;
    1.20 +                continue;
    1.21 +            default:
    1.22 +                break;
    1.23 +        }
    1.24 +        break;
    1.25 +    }
    1.26 +    return current;
    1.27 +}
    1.28 +
    1.29 +PEP_STATUS check_for_zero_fpr(char* fpr) {
    1.30 +    PEP_STATUS status = PEP_TRUSTWORDS_DUPLICATE_FPR;
    1.31 +    
    1.32 +    while (*fpr) {
    1.33 +        if (*fpr != '0') {
    1.34 +            status = PEP_STATUS_OK;
    1.35 +            break;
    1.36 +        }
    1.37 +        fpr++;    
    1.38 +    }
    1.39 +    
    1.40 +    return status;
    1.41 +    
    1.42 +}
    1.43 +
    1.44  DYNAMIC_API PEP_STATUS get_trustwords(
    1.45      PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    1.46      const char* lang, char **words, size_t *wsize, bool full
    1.47 @@ -2343,6 +2380,8 @@
    1.48  
    1.49      int SHORT_NUM_TWORDS = 5; 
    1.50      
    1.51 +    PEP_STATUS status = PEP_STATUS_OK;
    1.52 +    
    1.53      if (!(session && id1 && id2 && words && wsize) ||
    1.54          !(id1->fpr) || (!id2->fpr))
    1.55          return PEP_ILLEGAL_VALUE;
    1.56 @@ -2350,43 +2389,88 @@
    1.57      char *source1 = id1->fpr;
    1.58      char *source2 = id2->fpr;
    1.59  
    1.60 -    // in principle this should be the same, but maybe with other protocols it won't 
    1.61      int source1_len = strlen(source1);
    1.62      int source2_len = strlen(source2);
    1.63 -    int joint_len;
    1.64      int max_len;
    1.65          
    1.66      *words = NULL;    
    1.67      *wsize = 0;
    1.68  
    1.69      max_len = (source1_len > source2_len ? source1_len : source2_len);
    1.70 -    joint_len = (source1_len > source2_len ? source2_len : source1_len);
    1.71      
    1.72 -    char* XORed_fpr = (char*)(calloc(max_len + 1, 1));
    1.73 +    char* XORed_fpr = (char*)(calloc(1,max_len + 1));
    1.74 +    *(XORed_fpr + max_len) = '\0';
    1.75 +    char* result_curr = XORed_fpr + max_len - 1;
    1.76 +    char* source1_curr = source1 + source1_len - 1;
    1.77 +    char* source2_curr = source2 + source2_len - 1;
    1.78 +
    1.79 +    while (source1 <= source1_curr && source2 <= source2_curr) {
    1.80 +        source1_curr = skip_separators(source1_curr, source1);
    1.81 +        source2_curr = skip_separators(source2_curr, source2);
    1.82 +        
    1.83 +        if (source1_curr < source1 || source2_curr < source2)
    1.84 +            break;
    1.85 +            
    1.86 +        char xor_hex = xor_hex_chars(*source1_curr, *source2_curr);
    1.87 +        if (xor_hex == '\0') {
    1.88 +            status = PEP_ILLEGAL_VALUE;
    1.89 +            goto error_release;
    1.90 +        }
    1.91 +        
    1.92 +        *result_curr = xor_hex;
    1.93 +        result_curr--; source1_curr--; source2_curr--;
    1.94 +    }
    1.95 +
    1.96 +    char* remainder_start = NULL;
    1.97 +    char* remainder_curr = NULL;
    1.98      
    1.99 -    int i = 0;
   1.100 -    
   1.101 -    while (i < joint_len) {
   1.102 -        XORed_fpr[i] = xor_hex_chars(*source1, *source2);
   1.103 -        i++; source1++; source2++;
   1.104 +    if (source1 <= source1_curr) {
   1.105 +        remainder_start = source1;
   1.106 +        remainder_curr = source1_curr;
   1.107      }
   1.108 -    
   1.109 -    if (joint_len != max_len) {
   1.110 -        char* remainder_char = (source1_len > source2_len ? source1 : source2);        
   1.111 -        while (i < max_len) {
   1.112 -            XORed_fpr[i] = *remainder_char;
   1.113 -            i++; remainder_char++;
   1.114 +    else if (source2 <= source2_curr) {
   1.115 +        remainder_start = source2;
   1.116 +        remainder_curr = source2_curr;
   1.117 +    }
   1.118 +    if (remainder_curr) {
   1.119 +        while (remainder_start <= remainder_curr) {
   1.120 +            remainder_curr = skip_separators(remainder_curr, remainder_start);
   1.121 +            
   1.122 +            if (remainder_curr < remainder_start)
   1.123 +                break;
   1.124 +            
   1.125 +            char the_char = *remainder_curr;
   1.126 +            
   1.127 +            if (asciihex_to_num(the_char) < 0) {
   1.128 +                status = PEP_ILLEGAL_VALUE;
   1.129 +                goto error_release;
   1.130 +            }
   1.131 +            
   1.132 +            *result_curr = the_char;                
   1.133 +            result_curr--;
   1.134 +            remainder_curr--;
   1.135          }
   1.136      }
   1.137      
   1.138 -    XORed_fpr[max_len] = '\0';
   1.139 +    result_curr++;
   1.140 +
   1.141 +    if (result_curr > XORed_fpr) {
   1.142 +        char* tempstr = strdup(result_curr);
   1.143 +        free(XORed_fpr);
   1.144 +        XORed_fpr = tempstr;
   1.145 +    }
   1.146 +    
   1.147 +    status = check_for_zero_fpr(XORed_fpr);
   1.148 +    
   1.149 +    if (status != PEP_STATUS_OK)
   1.150 +        goto error_release;
   1.151      
   1.152      size_t max_words_per_id = (full ? 0 : SHORT_NUM_TWORDS);
   1.153  
   1.154      char* the_words = NULL;
   1.155      size_t the_size = 0;
   1.156  
   1.157 -    PEP_STATUS status = trustwords(session, XORed_fpr, lang, &the_words, &the_size, max_words_per_id);
   1.158 +    status = trustwords(session, XORed_fpr, lang, &the_words, &the_size, max_words_per_id);
   1.159      if (status != PEP_STATUS_OK)
   1.160          goto error_release;
   1.161  
     2.1 --- a/src/pEpEngine.h	Wed Jun 14 18:58:09 2017 +0200
     2.2 +++ b/src/pEpEngine.h	Thu Jun 15 18:44:07 2017 +0200
     2.3 @@ -68,6 +68,7 @@
     2.4  
     2.5      PEP_TRUSTWORD_NOT_FOUND                         = 0x0501,
     2.6      PEP_TRUSTWORDS_FPR_WRONG_LENGTH                 = 0x0502,
     2.7 +    PEP_TRUSTWORDS_DUPLICATE_FPR                    = 0x0503,
     2.8  
     2.9      PEP_CANNOT_CREATE_KEY                           = 0x0601,
    2.10      PEP_CANNOT_SEND_KEY                             = 0x0602,
     3.1 --- a/test/trustwords_test.cc	Wed Jun 14 18:58:09 2017 +0200
     3.2 +++ b/test/trustwords_test.cc	Thu Jun 15 18:44:07 2017 +0200
     3.3 @@ -14,6 +14,7 @@
     3.4      cout << "\n*** get_trustwords test ***\n\n";
     3.5  
     3.6      PEP_SESSION session = nullptr;
     3.7 +    PEP_STATUS status;
     3.8      
     3.9      cout << "calling init()\n";
    3.10      PEP_STATUS status1 = init(&session);
    3.11 @@ -55,29 +56,33 @@
    3.12      assert(words1);
    3.13      cout << words1 << "\n";
    3.14  
    3.15 +    free(words1);
    3.16 +    words1 = nullptr;
    3.17 +    
    3.18      cout << "\nfinding German trustwords for " << fingerprint2 << "...\n";
    3.19      trustwords(session, fingerprint2.c_str(), "de", &words2, &wsize2, 5);
    3.20      assert(words2);
    3.21      cout << words2 << "\n";
    3.22  
    3.23 +    free(words2);
    3.24 +    words1 = nullptr;
    3.25 +
    3.26      cout << "\nfinding German trustwords for " << identity1->address << " and " << identity2->address << "...\n";
    3.27      get_trustwords(session, identity1, identity2, "de", &full_wordlist, &wsize_full, false);
    3.28      assert(full_wordlist);
    3.29      cout << full_wordlist << "\n";
    3.30  
    3.31 -    cout << "\nfinding Englis trustwords for " << identity1->address << " and " << identity2->address << "... with spaces\n";
    3.32 +    free(full_wordlist);
    3.33 +    full_wordlist = nullptr;
    3.34 +
    3.35 +    cout << "\nfinding English trustwords for " << identity1->address << " and " << identity2->address << "... with spaces\n";
    3.36      get_trustwords(session, identity1, identity2_with_spaces, "en", &full_wordlist, &wsize_full, false);
    3.37      assert(full_wordlist);
    3.38      cout << full_wordlist << "\n";
    3.39 +
    3.40 +    free(full_wordlist);
    3.41 +    full_wordlist = nullptr;
    3.42      
    3.43 -    
    3.44 -    pEp_free(words1);
    3.45 -    words1 = nullptr;
    3.46 -    pEp_free(words2);
    3.47 -    words2 = nullptr;
    3.48 -    pEp_free(full_wordlist);
    3.49 -    full_wordlist = nullptr;
    3.50 -
    3.51      cout << "\nTest 2: fpr1 == fpr1, short" << endl;
    3.52      
    3.53      cout << "\nfinding French trustwords for " << fingerprint2 << "...\n";
    3.54 @@ -86,14 +91,14 @@
    3.55      cout << words1 << "\n";
    3.56          
    3.57      cout << "\nfinding French trustwords for " << identity2->address << " and " << identity2->address << "...\n";
    3.58 -    get_trustwords(session, identity2, identity2, "fr", &full_wordlist, &wsize_full, false);
    3.59 -    assert(full_wordlist);
    3.60 -    cout << full_wordlist << "\n";
    3.61 +    status = get_trustwords(session, identity2, identity2, "fr", &full_wordlist, &wsize_full, false);
    3.62 +    assert(status == PEP_TRUSTWORDS_DUPLICATE_FPR);
    3.63 +    cout << "Discovered duplicate fprs as desired" << endl;
    3.64  
    3.65      cout << "\nfinding English trustwords for " << identity2->address << " and " << identity2->address << "... with spaces\n";
    3.66      get_trustwords(session, identity2, identity2_with_spaces, "en", &full_wordlist, &wsize_full, false);
    3.67 -    assert(full_wordlist);
    3.68 -    cout << full_wordlist << "\n";
    3.69 +    assert(status == PEP_TRUSTWORDS_DUPLICATE_FPR);
    3.70 +    cout << "Discovered duplicate fprs as desired" << endl;
    3.71  
    3.72      pEp_free(words1);
    3.73      words1 = nullptr;
    3.74 @@ -112,13 +117,13 @@
    3.75      assert(words2);
    3.76      cout << words2 << "\n";
    3.77      
    3.78 -    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity2->address << "...\n";
    3.79 +    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity1->address << "...\n";
    3.80      get_trustwords(session, identity2, identity1, "en", &full_wordlist, &wsize_full, true);
    3.81      assert(full_wordlist);
    3.82      cout << full_wordlist << "\n";
    3.83      
    3.84 -    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity2->address << "... with spaces\n";
    3.85 -    get_trustwords(session, identity2_with_spaces, identity1, "en", &full_wordlist, &wsize_full, false);
    3.86 +    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity1->address << "... with spaces\n";
    3.87 +    get_trustwords(session, identity2_with_spaces, identity1, "en", &full_wordlist, &wsize_full, true);
    3.88      assert(full_wordlist);
    3.89      cout << full_wordlist << "\n";
    3.90      
    3.91 @@ -199,18 +204,18 @@
    3.92      pEp_free(full_wordlist);
    3.93      full_wordlist = nullptr;
    3.94  
    3.95 -    cout << "\nTest 6: fpr2 is too short" << endl;
    3.96 +    cout << "\nTest 6: fpr2 is shorter" << endl;
    3.97      
    3.98      pEp_identity* identity6 = new_identity(
    3.99          "nobody4@kgrothoff.org",
   3.100 -        "01F932086185C15917B72D30571AFBCA5493553",
   3.101 +        "F1F932086185C15917B72D30571AFBCA5493553",
   3.102          "blargh",
   3.103          "Krista Grothoff");
   3.104      
   3.105      cout << "\nfinding Turkish trustwords for " << identity5->address << " and " << identity6->address << "...\n";
   3.106      PEP_STATUS status6 = get_trustwords(session, identity5, identity6, "tr", &full_wordlist, &wsize_full, false);
   3.107 -    assert(status6 == PEP_TRUSTWORDS_FPR_WRONG_LENGTH);
   3.108 -    cout << "Bad fpr length correctly recognised." << "\n";
   3.109 +    assert(status6 == PEP_STATUS_OK);
   3.110 +    cout << full_wordlist << endl;
   3.111      
   3.112      pEp_identity* identity7 = new_identity(
   3.113          "nobody5@kgrothoff.org",
   3.114 @@ -238,4 +243,3 @@
   3.115      release(session);
   3.116      return 0;
   3.117  }
   3.118 -