ENGINE-215: needs to be tested, test cases impacted by the change need to be adjusted ENGINE-215
authorKrista Bennett <krista@pep-project.org>
Wed, 14 Jun 2017 18:52:55 +0200
branchENGINE-215
changeset 185699348d336639
parent 1852 8b786dad8b60
child 1857 52e46f43ac67
ENGINE-215: needs to be tested, test cases impacted by the change need to be adjusted
src/message_api.c
     1.1 --- a/src/message_api.c	Mon Jun 12 22:37:40 2017 +0200
     1.2 +++ b/src/message_api.c	Wed Jun 14 18:52:55 2017 +0200
     1.3 @@ -2297,6 +2297,37 @@
     1.4      return PEP_color_no_color;
     1.5  }
     1.6  
     1.7 +/* [0-9]: 0x30 - 0x39; [A-F] = 0x41 - 0x46; [a-f] = 0x61 - 0x66 */
     1.8 +static short asciihex_to_num(char a) {
     1.9 +    short conv_num = -1;
    1.10 +    if (a >= 0x30 && a <= 0x39)
    1.11 +        conv_num = a - 0x30;
    1.12 +    else {
    1.13 +        // convert case, subtract offset, get number
    1.14 +        conv_num = ((a | 0x20) - 0x61) + 10;
    1.15 +        if (conv_num < 0xa || conv_num > 0xf)
    1.16 +            conv_num = -1;
    1.17 +    }
    1.18 +    return conv_num;
    1.19 +}
    1.20 +
    1.21 +static char num_to_asciihex(short h) {
    1.22 +    if (h < 0 || h > 16)
    1.23 +        return '\0';
    1.24 +    if (h < 10)
    1.25 +        return (char)(h + 0x30);
    1.26 +    return (char)((h - 10) + 0x41); // for readability
    1.27 +}
    1.28 +
    1.29 +static char xor_hex_chars(char a, char b) {
    1.30 +    short a_num = asciihex_to_num(a);
    1.31 +    short b_num = asciihex_to_num(b);
    1.32 +    if (a_num < 0 || b_num < 0)
    1.33 +        return '\0';
    1.34 +    short xor_num = a_num^b_num;
    1.35 +    return num_to_asciihex(xor_num);
    1.36 +}
    1.37 +
    1.38  DYNAMIC_API PEP_STATUS get_trustwords(
    1.39      PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    1.40      const char* lang, char **words, size_t *wsize, bool full
    1.41 @@ -2310,95 +2341,66 @@
    1.42      assert(words);
    1.43      assert(wsize);
    1.44  
    1.45 +    int SHORT_NUM_TWORDS = 5; 
    1.46 +    
    1.47      if (!(session && id1 && id2 && words && wsize) ||
    1.48          !(id1->fpr) || (!id2->fpr))
    1.49          return PEP_ILLEGAL_VALUE;
    1.50  
    1.51 -    const char *source1 = id1->fpr;
    1.52 -    const char *source2 = id2->fpr;
    1.53 -
    1.54 -    *words = NULL;
    1.55 +    char *source1 = id1->fpr;
    1.56 +    char *source2 = id2->fpr;
    1.57 +
    1.58 +    // in principle this should be the same, but maybe with other protocols it won't 
    1.59 +    int source1_len = strlen(source1);
    1.60 +    int source2_len = strlen(source2);
    1.61 +    int joint_len;
    1.62 +    int max_len;
    1.63 +        
    1.64 +    *words = NULL;    
    1.65      *wsize = 0;
    1.66  
    1.67 -    const size_t SHORT_NUM_TWORDS = 5;
    1.68 -
    1.69 -    // N.B. THIS will have to be changed once we start checking trustword entropy.
    1.70 -    // For now, full is ALL, and otherwise it's 5-per-id.
    1.71 -    size_t max_words_per_id = (full ? 0 : SHORT_NUM_TWORDS);
    1.72 -
    1.73 -    char* first_set = NULL;
    1.74 -    char* second_set = NULL;
    1.75 -    size_t first_wsize = 0;
    1.76 -    size_t second_wsize = 0;
    1.77 -
    1.78 -    int fpr_comparison = -255;
    1.79 -    PEP_STATUS status = _compare_fprs(source1, strlen(source1), source2, strlen(source2), &fpr_comparison);
    1.80 -    if (status != PEP_STATUS_OK)
    1.81 -        return status;
    1.82 -
    1.83 -    char* _retstr = NULL;
    1.84 -
    1.85 -    switch (fpr_comparison) {
    1.86 -        case 1: // source1 > source2
    1.87 -            status = trustwords(session, source2, lang, &first_set, &first_wsize, max_words_per_id);
    1.88 -            if (status != PEP_STATUS_OK)
    1.89 -                goto error_release;
    1.90 -            status = trustwords(session, source1, lang, &second_set, &second_wsize, max_words_per_id);
    1.91 -            if (status != PEP_STATUS_OK)
    1.92 -                goto error_release;
    1.93 -            break;
    1.94 -        case 0:
    1.95 -        case -1: // source1 <= source2
    1.96 -            status = trustwords(session, source1, lang, &first_set, &first_wsize, max_words_per_id);
    1.97 -            if (status != PEP_STATUS_OK)
    1.98 -                goto error_release;
    1.99 -            status = trustwords(session, source2, lang, &second_set, &second_wsize, max_words_per_id);
   1.100 -            if (status != PEP_STATUS_OK)
   1.101 -                goto error_release;
   1.102 -            break;
   1.103 -        default:
   1.104 -            return ERROR(PEP_UNKNOWN_ERROR); // shouldn't be possible
   1.105 +    max_len = (source1_len > source2_len ? source1_len : source2_len);
   1.106 +    joint_len = (source1_len > source2_len ? source2_len : source1_len);
   1.107 +    
   1.108 +    char* XORed_fpr = (char*)(calloc(max_len + 1, 1));
   1.109 +    
   1.110 +    int i = 0;
   1.111 +    
   1.112 +    while (i < joint_len) {
   1.113 +        XORed_fpr[i] = xor_hex_chars(*source1, *source2);
   1.114 +        i++; source1++; source2++;
   1.115      }
   1.116 -
   1.117 -    size_t _wsize = first_wsize + second_wsize;
   1.118 -
   1.119 -    bool needs_space = (first_set[first_wsize - 1] != ' ');
   1.120 -
   1.121 -    if (needs_space)
   1.122 -        _wsize++;
   1.123 -
   1.124 -    _retstr = calloc(1, _wsize + 1);
   1.125 -
   1.126 -    size_t len = strlcpy(_retstr, first_set, _wsize);
   1.127 -    if (len >= _wsize) {
   1.128 -        status = PEP_UNKNOWN_ERROR;
   1.129 -        goto error_release;
   1.130 -    }
   1.131 -    if (needs_space) {
   1.132 -        strlcat(_retstr, " ", _wsize);
   1.133 -        if (len >= _wsize) {
   1.134 -            status = PEP_UNKNOWN_ERROR;
   1.135 -            goto error_release;
   1.136 +    
   1.137 +    if (joint_len != max_len) {
   1.138 +        char* remainder_char = (source1_len > source2_len ? source1 : source2);        
   1.139 +        while (i < max_len) {
   1.140 +            XORed_fpr[i] = *remainder_char;
   1.141 +            i++; remainder_char++;
   1.142          }
   1.143      }
   1.144 -    strlcat(_retstr, second_set, _wsize);
   1.145 -    if (len >= _wsize){
   1.146 -        status = PEP_UNKNOWN_ERROR;
   1.147 +    
   1.148 +    XORed_fpr[max_len] = '\0';
   1.149 +    
   1.150 +    size_t max_words_per_id = (full ? 0 : SHORT_NUM_TWORDS);
   1.151 +
   1.152 +    char* the_words = NULL;
   1.153 +    size_t the_size = 0;
   1.154 +
   1.155 +    PEP_STATUS status = trustwords(session, XORed_fpr, lang, &the_words, &the_size, max_words_per_id);
   1.156 +    if (status != PEP_STATUS_OK)
   1.157          goto error_release;
   1.158 -    }
   1.159 -
   1.160 -    *words = _retstr;
   1.161 -    *wsize = _wsize;
   1.162 +
   1.163 +    *words = the_words;
   1.164 +    *wsize = the_size;
   1.165 +    
   1.166      status = PEP_STATUS_OK;
   1.167  
   1.168      goto the_end;
   1.169  
   1.170      error_release:
   1.171 -    free(_retstr);
   1.172 -
   1.173 +        free (XORed_fpr);
   1.174 +        
   1.175      the_end:
   1.176 -    free(first_set);
   1.177 -    free(second_set);
   1.178      return ERROR(status);
   1.179  }
   1.180