Skip to content

Commit

Permalink
Calculate a verification key that matches KDE/Android (#1493)
Browse files Browse the repository at this point in the history
* Calculate a verification key that matches KDE/Android
* Remove dead code and satisfy linter
  • Loading branch information
daniellandau authored Oct 23, 2022
1 parent 4d0becc commit 6c20f96
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 35 deletions.
48 changes: 26 additions & 22 deletions src/service/__init__.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,48 +354,52 @@ Gio.TlsCertificate.new_for_paths = function (certPath, keyPath, commonName = nul

Object.defineProperties(Gio.TlsCertificate.prototype, {
/**
* Compute a SHA256 fingerprint of the certificate.
* See: https://gitlab.gnome.org/GNOME/glib/issues/1290
*
* @return {string} A SHA256 fingerprint of the certificate.
* The common name of the certificate.
*/
'sha256': {
value: function () {
if (!this.__fingerprint) {
'common_name': {
get: function () {
if (!this.__common_name) {
const proc = new Gio.Subprocess({
argv: [Config.OPENSSL_PATH, 'x509', '-noout', '-fingerprint', '-sha256', '-inform', 'pem'],
argv: [Config.OPENSSL_PATH, 'x509', '-noout', '-subject', '-inform', 'pem'],
flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE,
});
proc.init(null);

const stdout = proc.communicate_utf8(this.certificate_pem, null)[1];
this.__fingerprint = /[a-zA-Z0-9:]{95}/.exec(stdout)[0];
this.__common_name = /(?:cn|CN) ?= ?([^,\n]*)/.exec(stdout)[1];
}

return this.__fingerprint;
return this.__common_name;
},
enumerable: false,
enumerable: true,
},

/**
* The common name of the certificate.
* Get just the pubkey as a DER ByteArray of a certificate.
*
* @return {GLib.Bytes} The pubkey as DER of the certificate.
*/
'common_name': {
get: function () {
if (!this.__common_name) {
const proc = new Gio.Subprocess({
argv: [Config.OPENSSL_PATH, 'x509', '-noout', '-subject', '-inform', 'pem'],
'pubkey_der': {
value: function () {
if (!this.__pubkey_der) {
let proc = new Gio.Subprocess({
argv: [Config.OPENSSL_PATH, 'x509', '-noout', '-pubkey', '-inform', 'pem'],
flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE,
});
proc.init(null);

const stdout = proc.communicate_utf8(this.certificate_pem, null)[1];
this.__common_name = /(?:cn|CN) ?= ?([^,\n]*)/.exec(stdout)[1];
const pubkey = proc.communicate_utf8(this.certificate_pem, null)[1];
proc = new Gio.Subprocess({
argv: [Config.OPENSSL_PATH, 'pkey', '-pubin', '-inform', 'pem', '-outform', 'der'],
flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE,
});
proc.init(null);
this.__pubkey_der = proc.communicate(ByteArray.fromString(pubkey), null)[1];
}

return this.__common_name;
return this.__pubkey_der;
},
enumerable: true,
enumerable: false,
},
});

});
36 changes: 23 additions & 13 deletions src/service/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const ByteArray = imports.byteArray;

const Config = imports.config;
const Components = imports.service.components;
Expand Down Expand Up @@ -159,8 +160,8 @@ var Device = GObject.registerClass({

// FIXME: backend should do this stuff
get encryption_info() {
let remoteFingerprint = _('Not available');
let localFingerprint = _('Not available');
let localCert = null;
let remoteCert = null;

// Bluetooth connections have no certificate so we use the host address
if (this.connection_type === 'bluetooth') {
Expand All @@ -169,14 +170,14 @@ var Device = GObject.registerClass({

// If the device is connected use the certificate from the connection
} else if (this.connected) {
remoteFingerprint = this.channel.peer_certificate.sha256();
remoteCert = this.channel.peer_certificate;

// Otherwise pull it out of the settings
} else if (this.paired) {
remoteFingerprint = Gio.TlsCertificate.new_from_pem(
remoteCert = Gio.TlsCertificate.new_from_pem(
this.settings.get_string('certificate-pem'),
-1
).sha256();
);
}

// FIXME: another ugly reach-around
Expand All @@ -186,18 +187,27 @@ var Device = GObject.registerClass({
lanBackend = this.service.manager.backends.get('lan');

if (lanBackend && lanBackend.certificate)
localFingerprint = lanBackend.certificate.sha256();
localCert = lanBackend.certificate;


let verificationKey = '';
if (localCert && remoteCert) {
let a = localCert.pubkey_der();
let b = remoteCert.pubkey_der();
if (a.compare(b) < 0)
[a, b] = [b, a]; // swap
const checksum = new GLib.Checksum(GLib.ChecksumType.SHA256);
checksum.update(ByteArray.fromGBytes(a));
checksum.update(ByteArray.fromGBytes(b));
verificationKey = checksum.get_string();
}

// TRANSLATORS: Label for TLS Certificate fingerprint
// TRANSLATORS: Label for TLS connection verification key
//
// Example:
//
// Google Pixel Fingerprint:
// 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
return _('%s Fingerprint:').format(this.name) + '\n' +
remoteFingerprint + '\n\n' +
_('%s Fingerprint:').format('GSConnect') + '\n' +
localFingerprint;
// Verification key: 0123456789abcdef000000000000000000000000
return _('Verification key: %s').format(verificationKey);
}

get id() {
Expand Down

0 comments on commit 6c20f96

Please sign in to comment.