ENGINE-109: fixed fpr comparison. Urgh.
authorKrista Grothoff <krista@pep-project.org>
Tue, 18 Oct 2016 19:23:51 +0200
changeset 1312e90df3390555
parent 1308 df40e76a86fc
child 1313 0869ca4214df
ENGINE-109: fixed fpr comparison. Urgh.
src/message_api.c
src/pEpEngine.h
     1.1 --- a/src/message_api.c	Tue Oct 18 17:23:39 2016 +0200
     1.2 +++ b/src/message_api.c	Tue Oct 18 19:23:51 2016 +0200
     1.3 @@ -1907,6 +1907,74 @@
     1.4      assert(false);
     1.5  }
     1.6  
     1.7 +// Returns, in comparison: 1 if fpr1 > fpr2, 0 if equal, -1 if fpr1 < fpr2
     1.8 +static PEP_STATUS _compare_fprs(const char* fpr1, const char* fpr2, int* comparison) {
     1.9 +    
    1.10 +    const int _FULL_FINGERPRINT_LENGTH = 40;
    1.11 +    const int _ASCII_LOWERCASE_OFFSET = 32;
    1.12 +
    1.13 +    size_t fpr1_len = strlen(fpr1);
    1.14 +    size_t fpr2_len = strlen(fpr2);
    1.15 +    
    1.16 +    if (fpr1_len != _FULL_FINGERPRINT_LENGTH || fpr2_len != _FULL_FINGERPRINT_LENGTH)
    1.17 +        return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
    1.18 +    
    1.19 +    const char* fpr1_curr = fpr1;
    1.20 +    const char* fpr2_curr = fpr2;
    1.21 +    
    1.22 +    char current;
    1.23 +
    1.24 +    for (current = *fpr1_curr; current != '0' && current != '\0'; fpr1_curr++, fpr1_len--);
    1.25 +    for (current = *fpr2_curr; current != '0' && current != '\0'; fpr2_curr++, fpr2_len--);
    1.26 +    
    1.27 +    if (fpr1_len == fpr2_len) {
    1.28 +        char digit1;
    1.29 +        char digit2;
    1.30 +
    1.31 +        while (fpr1_curr) {
    1.32 +            digit1 = *fpr1_curr++;
    1.33 +            digit2 = *fpr2_curr++;
    1.34 +
    1.35 +            // Adjust for case-insensitive compare
    1.36 +            if (digit1 >= 'a' && digit1 <= 'f')
    1.37 +                digit1 -= _ASCII_LOWERCASE_OFFSET;
    1.38 +            if (digit2 >= 'a' && digit2 <= 'f')
    1.39 +                digit2 -= _ASCII_LOWERCASE_OFFSET;
    1.40 +            
    1.41 +            if (!((digit1 >= '0' && digit1 <= '9') ||
    1.42 +                  (digit1 >= 'a' && digit1 <= 'f'))
    1.43 +                || 
    1.44 +                !((digit2 >= '0' && digit2 <= '9') ||
    1.45 +                     (digit2 >= 'a' && digit2 <= 'f'))) {
    1.46 +                return PEP_ILLEGAL_VALUE;
    1.47 +            }
    1.48 +            
    1.49 +            // Otherwise...
    1.50 +            // We take advantage of the fact that 'a'-'f' are larger
    1.51 +            // integer values in the ASCII table than '0'-'9'.
    1.52 +            // This allows us to compare digits directly.
    1.53 +            if (digit1 > digit2) {
    1.54 +                *comparison = 1;
    1.55 +                return PEP_STATUS_OK;
    1.56 +            } else if (digit1 < digit2) {
    1.57 +                *comparison = -1;
    1.58 +                return PEP_STATUS_OK;
    1.59 +            }
    1.60 +            
    1.61 +            // pointers already advanced above. Keep going.
    1.62 +        }
    1.63 +        *comparison = 0;
    1.64 +        return PEP_STATUS_OK;
    1.65 +    }
    1.66 +    else if (fpr1_len > fpr2_len) {
    1.67 +        *comparison = 1;
    1.68 +        return PEP_STATUS_OK;
    1.69 +    }
    1.70 +    // Otherwise, fpr1_len < fpr2_len
    1.71 +    *comparison = -1;
    1.72 +    return PEP_STATUS_OK;
    1.73 +}
    1.74 +
    1.75  DYNAMIC_API PEP_STATUS get_trustwords(
    1.76      PEP_SESSION session, pEp_identity* id1, pEp_identity* id2,
    1.77      const char* lang, char **words, size_t *wsize, bool full
    1.78 @@ -1940,26 +2008,35 @@
    1.79      char* second_set = NULL;
    1.80      size_t first_wsize = 0;
    1.81      size_t second_wsize = 0;
    1.82 -    PEP_STATUS status = PEP_UNKNOWN_ERROR;
    1.83      
    1.84 +    int fpr_comparison = -255;
    1.85 +    PEP_STATUS status = _compare_fprs(source1, source2, &fpr_comparison);
    1.86 +    if (status != PEP_STATUS_OK)
    1.87 +        return status;
    1.88 +
    1.89      char* _retstr = NULL;
    1.90 +
    1.91 +    switch (fpr_comparison) {
    1.92 +        case 1: // source1 > source2
    1.93 +            status = trustwords(session, source2, lang, &first_set, &first_wsize, max_words_per_id);
    1.94 +            if (status != PEP_STATUS_OK)
    1.95 +                goto error_release;
    1.96 +            status = trustwords(session, source1, lang, &second_set, &second_wsize, max_words_per_id); 
    1.97 +            if (status != PEP_STATUS_OK)
    1.98 +                goto error_release;
    1.99 +            break;
   1.100 +        case 0: 
   1.101 +        case -1: // source1 <= source2
   1.102 +            status = trustwords(session, source1, lang, &first_set, &first_wsize, max_words_per_id);
   1.103 +            if (status != PEP_STATUS_OK)
   1.104 +                goto error_release;
   1.105 +            status = trustwords(session, source2, lang, &second_set, &second_wsize, max_words_per_id); 
   1.106 +            if (status != PEP_STATUS_OK)
   1.107 +                goto error_release;
   1.108 +        default:
   1.109 +            return PEP_UNKNOWN_ERROR; // shouldn't be possible
   1.110 +    }
   1.111      
   1.112 -    if (source1 > source2) {
   1.113 -        status = trustwords(session, source2, lang, &first_set, &first_wsize, max_words_per_id);
   1.114 -        if (status != PEP_STATUS_OK)
   1.115 -            goto error_release;
   1.116 -        status = trustwords(session, source1, lang, &second_set, &second_wsize, max_words_per_id); 
   1.117 -        if (status != PEP_STATUS_OK)
   1.118 -            goto error_release;
   1.119 -    }
   1.120 -    else {
   1.121 -        status = trustwords(session, source1, lang, &first_set, &first_wsize, max_words_per_id);
   1.122 -        if (status != PEP_STATUS_OK)
   1.123 -            goto error_release;
   1.124 -        status = trustwords(session, source2, lang, &second_set, &second_wsize, max_words_per_id); 
   1.125 -        if (status != PEP_STATUS_OK)
   1.126 -            goto error_release;
   1.127 -    }
   1.128      size_t _wsize = first_wsize + second_wsize;
   1.129      
   1.130      _retstr = calloc(1, _wsize + 1);
     2.1 --- a/src/pEpEngine.h	Tue Oct 18 17:23:39 2016 +0200
     2.2 +++ b/src/pEpEngine.h	Tue Oct 18 19:23:51 2016 +0200
     2.3 @@ -63,6 +63,7 @@
     2.4      PEP_CANNOT_DECRYPT_UNKNOWN                      = 0x04ff,
     2.5  
     2.6      PEP_TRUSTWORD_NOT_FOUND                         = 0x0501,
     2.7 +    PEP_TRUSTWORDS_FPR_WRONG_LENGTH                 = 0x0502,
     2.8  
     2.9      PEP_CANNOT_CREATE_KEY                           = 0x0601,
    2.10      PEP_CANNOT_SEND_KEY                             = 0x0602,