2
0
Эх сурвалжийг харах

Properly generate and render fingerprints

JC Brand 6 жил өмнө
parent
commit
1dc1c1f98a

+ 4 - 0
sass/_modal.scss

@@ -23,6 +23,7 @@
             }
             }
             .fingerprint-removal {
             .fingerprint-removal {
                 label {
                 label {
+                    display: flex;
                     padding: 0.75rem 1.25rem;
                     padding: 0.75rem 1.25rem;
                 }
                 }
             }
             }
@@ -47,6 +48,9 @@
             display: flex;
             display: flex;
             justify-content: space-between;
             justify-content: space-between;
             font-size: 95%;
             font-size: 95%;
+            .fingerprint {
+                margin-left: 1em;
+            }
         }
         }
     }
     }
 }
 }

+ 4 - 2
spec/omemo.js

@@ -912,7 +912,7 @@
                             .c('bundle', {'xmlns': 'eu.siacs.conversations.axolotl'})
                             .c('bundle', {'xmlns': 'eu.siacs.conversations.axolotl'})
                                 .c('signedPreKeyPublic', {'signedPreKeyId': '4223'}).t(btoa('1111')).up()
                                 .c('signedPreKeyPublic', {'signedPreKeyId': '4223'}).t(btoa('1111')).up()
                                 .c('signedPreKeySignature').t(btoa('2222')).up()
                                 .c('signedPreKeySignature').t(btoa('2222')).up()
-                                .c('identityKey').t(btoa('3333')).up()
+                                .c('identityKey').t('BQmHEOHjsYm3w5M8VqxAtqJmLCi7CaxxsdZz6G0YpuMI').up()
                                 .c('prekeys')
                                 .c('prekeys')
                                     .c('preKeyPublic', {'preKeyId': '1'}).t(btoa('1001')).up()
                                     .c('preKeyPublic', {'preKeyId': '1'}).t(btoa('1001')).up()
                                     .c('preKeyPublic', {'preKeyId': '2'}).t(btoa('1002')).up()
                                     .c('preKeyPublic', {'preKeyId': '2'}).t(btoa('1002')).up()
@@ -927,7 +927,9 @@
                 const modal = view.user_details_modal;
                 const modal = view.user_details_modal;
                 expect(modal.el.querySelectorAll('.fingerprints .fingerprint').length).toBe(1);
                 expect(modal.el.querySelectorAll('.fingerprints .fingerprint').length).toBe(1);
                 const el = modal.el.querySelector('.fingerprints .fingerprint');
                 const el = modal.el.querySelector('.fingerprints .fingerprint');
-                expect(el.textContent).toBe('f56d6351aa71cff0debea014d13525e42036187a');
+                expect(el.textContent.trim()).toBe(
+                    u.formatFingerprint(u.arrayBufferToHex(u.base64ToArrayBuffer('BQmHEOHjsYm3w5M8VqxAtqJmLCi7CaxxsdZz6G0YpuMI')))
+                );
 
 
                 expect(modal.el.querySelectorAll('input[type="radio"]').length).toBe(2);
                 expect(modal.el.querySelectorAll('input[type="radio"]').length).toBe(2);
 
 

+ 2 - 1
src/converse-chatview.js

@@ -252,7 +252,8 @@
                         '_converse': _converse,
                         '_converse': _converse,
                         'allow_contact_removal': _converse.allow_contact_removal,
                         'allow_contact_removal': _converse.allow_contact_removal,
                         'display_name': this.model.getDisplayName(),
                         'display_name': this.model.getDisplayName(),
-                        'is_roster_contact': !_.isUndefined(this.model.contact)
+                        'is_roster_contact': !_.isUndefined(this.model.contact),
+                        'utils': u
                     }));
                     }));
                 },
                 },
 
 

+ 6 - 7
src/converse-omemo.js

@@ -49,7 +49,7 @@
                 }
                 }
             });
             });
         return {
         return {
-            'identity_key': bundle_el.querySelector('identityKey').textContent,
+            'identity_key': bundle_el.querySelector('identityKey').textContent.trim(),
             'signed_prekey': {
             'signed_prekey': {
                 'id': parseInt(signed_prekey_public_el.getAttribute('signedPreKeyId'), 10),
                 'id': parseInt(signed_prekey_public_el.getAttribute('signedPreKeyId'), 10),
                 'public_key': signed_prekey_public_el.textContent,
                 'public_key': signed_prekey_public_el.textContent,
@@ -490,12 +490,11 @@
             _converse.NUM_PREKEYS = 100; // Set here so that tests can override
             _converse.NUM_PREKEYS = 100; // Set here so that tests can override
 
 
             function generateFingerprint (device) {
             function generateFingerprint (device) {
-                let bundle;
-                return device.getBundle().then(b => {
-                    bundle = b;
-                    return crypto.subtle.digest('SHA-1', u.base64ToArrayBuffer(bundle['identity_key']));
-                }).then(fp => {
-                    bundle['fingerprint'] = u.arrayBufferToHex(fp);
+                if (_.get(device.get('bundle'), 'fingerprint')) {
+                    return;
+                }
+                return device.getBundle().then(bundle => {
+                    bundle['fingerprint'] = u.arrayBufferToHex(u.base64ToArrayBuffer(bundle['identity_key']));
                     device.save('bundle', bundle);
                     device.save('bundle', bundle);
                     device.trigger('change:bundle'); // Doesn't get triggered automatically due to pass-by-reference
                     device.trigger('change:bundle'); // Doesn't get triggered automatically due to pass-by-reference
                 });
                 });

+ 1 - 0
src/converse-profile.js

@@ -74,6 +74,7 @@
                         'label_role': __('Role'),
                         'label_role': __('Role'),
                         'label_role_help': __('Use commas to separate multiple roles. Your roles are shown next to your name on your chat messages.'),
                         'label_role_help': __('Use commas to separate multiple roles. Your roles are shown next to your name on your chat messages.'),
                         'label_url': __('URL'),
                         'label_url': __('URL'),
+                        'utils': u,
                         'view': this
                         'view': this
                     }));
                     }));
                 },
                 },

+ 2 - 2
src/templates/profile_modal.html

@@ -72,7 +72,7 @@
                                     <li class="list-group-item active">{{{o.__("This device's OMEMO fingerprint")}}}</li>
                                     <li class="list-group-item active">{{{o.__("This device's OMEMO fingerprint")}}}</li>
                                     <li class="list-group-item">
                                     <li class="list-group-item">
                                         {[ if (o.view.current_device.get('bundle') && o.view.current_device.get('bundle').fingerprint) { ]}
                                         {[ if (o.view.current_device.get('bundle') && o.view.current_device.get('bundle').fingerprint) { ]}
-                                            <span class="fingerprint">{{{o.view.current_device.get('bundle').fingerprint}}}</span>
+                                        <span class="fingerprint">{{{o.utils.formatFingerprint(o.view.current_device.get('bundle').fingerprint)}}}</span>
                                         {[ } else {]}
                                         {[ } else {]}
                                             <span class="spinner fa fa-spinner centered"/>
                                             <span class="spinner fa fa-spinner centered"/>
                                         {[ } ]}
                                         {[ } ]}
@@ -93,7 +93,7 @@
                                                 <label>
                                                 <label>
                                                 <input type="checkbox" value="{{{device.get('id')}}}"
                                                 <input type="checkbox" value="{{{device.get('id')}}}"
                                                        aria-label="{{{o.__('Checkbox for selecting the following fingerprint')}}}">
                                                        aria-label="{{{o.__('Checkbox for selecting the following fingerprint')}}}">
-                                                <span class="fingerprint">{{{device.get('bundle').fingerprint}}}</span>
+                                                <span class="fingerprint">{{{o.utils.formatFingerprint(device.get('bundle').fingerprint)}}}</span>
                                                 </label>
                                                 </label>
                                             </li>
                                             </li>
                                             {[ } else {]}
                                             {[ } else {]}

+ 1 - 1
src/templates/user_details_modal.html

@@ -50,7 +50,7 @@
                                                 {[ if (device.get('trusted') === -1) { ]} checked="checked" {[ } ]}>{{{o.__('Untrusted')}}}
                                                 {[ if (device.get('trusted') === -1) { ]} checked="checked" {[ } ]}>{{{o.__('Untrusted')}}}
                                         </label>
                                         </label>
                                     </div>
                                     </div>
-                                    <span class="fingerprint">{{{device.get('bundle').fingerprint}}}</span>
+                                    <span class="fingerprint">{{{o.utils.formatFingerprint(device.get('bundle').fingerprint)}}}</span>
                                     </form>
                                     </form>
                                 </li>
                                 </li>
                                 {[ } ]}
                                 {[ } ]}

+ 13 - 15
src/utils/core.js

@@ -912,20 +912,19 @@
         return result;
         return result;
     };
     };
 
 
-    u.arrayBufferToHex = function (ab) {
-        const hexCodes = [];
-        const padding = '00000000';
-        const view = new window.DataView(ab);
-        for (var i = 0; i < view.byteLength; i += 4) {
-            // Using getUint32 reduces the number of iterations needed (we process 4 bytes each time)
-            const value = view.getUint32(i)
-            // toString(16) will give the hex representation of the number without padding
-            const stringValue = value.toString(16)
-            // We use concatenation and slice for padding
-            const paddedValue = (padding + stringValue).slice(-padding.length)
-            hexCodes.push(paddedValue);
+    u.formatFingerprint = function (fp) {
+        fp = fp.replace(/^05/, '');
+        const arr = [];
+        for (let i=1; i<8; i++) {
+            const idx = i*8+i-1;
+            fp = fp.slice(0, idx) + ' ' + fp.slice(idx);
         }
         }
-        return hexCodes.join("");
+        return fp;
+    };
+
+    u.arrayBufferToHex = function (ab) {
+        // https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex#40031979
+        return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
     };
     };
 
 
     u.arrayBufferToString = function (ab) {
     u.arrayBufferToString = function (ab) {
@@ -934,8 +933,7 @@
     };
     };
 
 
     u.arrayBufferToBase64 = function (ab) {
     u.arrayBufferToBase64 = function (ab) {
-        return btoa(new Uint8Array(ab)
-            .reduce((data, byte) => data + String.fromCharCode(byte), ''));
+        return btoa((new Uint8Array(ab)).reduce((data, byte) => data + String.fromCharCode(byte), ''));
     };
     };
 
 
     u.stringToArrayBuffer = function (string) {
     u.stringToArrayBuffer = function (string) {