diff --git a/packages/moxxmpp/lib/src/xeps/xep_0300.dart b/packages/moxxmpp/lib/src/xeps/xep_0300.dart index 624cff7..6fdda6a 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0300.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0300.dart @@ -4,25 +4,57 @@ import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/stringxml.dart'; -XMLNode constructHashElement(String algo, String base64Hash) { +XMLNode constructHashElement(HashFunction hash, String value) { return XMLNode.xmlns( tag: 'hash', xmlns: hashXmlns, - attributes: {'algo': algo}, - text: base64Hash, + attributes: {'algo': hash.toName()}, + text: value, ); } enum HashFunction { + /// SHA-256 sha256, - sha512, - sha3_256, - sha3_512, - blake2b256, - blake2b512, -} -extension HashNameToEnumExtension on HashFunction { + /// SHA-256 + sha512, + + /// SHA3-256 + sha3_256, + + /// SHA3-512 + sha3_512, + + /// BLAKE2b-256 + blake2b256, + + /// BLAKE2b-512 + blake2b512; + + /// Get a HashFunction from its name [name] according to either + /// - IANA's hash name register (http://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xhtml) + /// - XEP-0300 + factory HashFunction.fromName(String name) { + switch (name) { + case hashSha256: + return HashFunction.sha256; + case hashSha512: + return HashFunction.sha512; + case hashSha3256: + return HashFunction.sha3_256; + case hashSha3512: + return HashFunction.sha3_512; + case hashBlake2b256: + return HashFunction.blake2b256; + case hashBlake2b512: + return HashFunction.blake2b512; + } + + throw Exception(); + } + + /// Return the hash function's name according to IANA's hash name register or XEP-0300. String toName() { switch (this) { case HashFunction.sha256: @@ -41,25 +73,6 @@ extension HashNameToEnumExtension on HashFunction { } } -HashFunction hashFunctionFromName(String name) { - switch (name) { - case hashSha256: - return HashFunction.sha256; - case hashSha512: - return HashFunction.sha512; - case hashSha3256: - return HashFunction.sha3_256; - case hashSha3512: - return HashFunction.sha3_512; - case hashBlake2b256: - return HashFunction.blake2b256; - case hashBlake2b512: - return HashFunction.blake2b512; - } - - throw Exception(); -} - class CryptographicHashManager extends XmppManagerBase { CryptographicHashManager() : super(cryptographicHashManager); diff --git a/packages/moxxmpp/lib/src/xeps/xep_0446.dart b/packages/moxxmpp/lib/src/xeps/xep_0446.dart index c768eaf..515c4e7 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0446.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0446.dart @@ -13,7 +13,7 @@ class FileMetadataData { this.name, this.size, required this.thumbnails, - Map? hashes, + Map? hashes, }) : hashes = hashes ?? const {}; /// Parse [node] as a FileMetadataData element. @@ -31,9 +31,11 @@ class FileMetadataData { final size = sizeElement != null ? int.parse(sizeElement.innerText()) : null; - final hashes = {}; + final hashes = {}; for (final e in node.findTags('hash')) { - hashes[e.attributes['algo']! as String] = e.innerText(); + final hashFunction = + HashFunction.fromName(e.attributes['algo']! as String); + hashes[hashFunction] = e.innerText(); } // Thumbnails @@ -75,7 +77,7 @@ class FileMetadataData { final int? height; final List thumbnails; final String? desc; - final Map hashes; + final Map hashes; final int? length; final String? name; final int? size; diff --git a/packages/moxxmpp/lib/src/xeps/xep_0448.dart b/packages/moxxmpp/lib/src/xeps/xep_0448.dart index 7c13639..545bd3d 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0448.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0448.dart @@ -8,10 +8,21 @@ import 'package:moxxmpp/src/xeps/xep_0447.dart'; enum SFSEncryptionType { aes128GcmNoPadding, aes256GcmNoPadding, - aes256CbcPkcs7, -} + aes256CbcPkcs7; + + factory SFSEncryptionType.fromNamespace(String xmlns) { + switch (xmlns) { + case sfsEncryptionAes128GcmNoPaddingXmlns: + return SFSEncryptionType.aes128GcmNoPadding; + case sfsEncryptionAes256GcmNoPaddingXmlns: + return SFSEncryptionType.aes256GcmNoPadding; + case sfsEncryptionAes256CbcPkcs7Xmlns: + return SFSEncryptionType.aes256CbcPkcs7; + } + + throw Exception(); + } -extension SFSEncryptionTypeNamespaceExtension on SFSEncryptionType { String toNamespace() { switch (this) { case SFSEncryptionType.aes128GcmNoPadding: @@ -24,19 +35,6 @@ extension SFSEncryptionTypeNamespaceExtension on SFSEncryptionType { } } -SFSEncryptionType encryptionTypeFromNamespace(String xmlns) { - switch (xmlns) { - case sfsEncryptionAes128GcmNoPaddingXmlns: - return SFSEncryptionType.aes128GcmNoPadding; - case sfsEncryptionAes256GcmNoPaddingXmlns: - return SFSEncryptionType.aes256GcmNoPadding; - case sfsEncryptionAes256CbcPkcs7Xmlns: - return SFSEncryptionType.aes256CbcPkcs7; - } - - throw Exception(); -} - class StatelessFileSharingEncryptedSource extends StatelessFileSharingSource { StatelessFileSharingEncryptedSource( this.encryption, @@ -63,13 +61,15 @@ class StatelessFileSharingEncryptedSource extends StatelessFileSharingSource { )!; // Find hashes - final hashes = {}; + final hashes = {}; for (final hash in element.findTags('hash', xmlns: hashXmlns)) { - hashes[hash.attributes['algo']! as String] = hash.text!; + final hashFunction = + HashFunction.fromName(hash.attributes['algo']! as String); + hashes[hashFunction] = hash.text!; } return StatelessFileSharingEncryptedSource( - encryptionTypeFromNamespace(element.attributes['cipher']! as String), + SFSEncryptionType.fromNamespace(element.attributes['cipher']! as String), key, iv, hashes, @@ -80,7 +80,7 @@ class StatelessFileSharingEncryptedSource extends StatelessFileSharingSource { final List key; final List iv; final SFSEncryptionType encryption; - final Map hashes; + final Map hashes; final StatelessFileSharingUrlSource source; @override diff --git a/packages/moxxmpp/lib/src/xeps/xep_0449.dart b/packages/moxxmpp/lib/src/xeps/xep_0449.dart index f67afab..426d208 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0449.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0449.dart @@ -87,7 +87,7 @@ class StickerPack { var hashValue = ''; if (hashAvailable) { final hash = node.firstTag('hash', xmlns: hashXmlns)!; - hashAlgorithm = hashFunctionFromName(hash.attributes['algo']! as String); + hashAlgorithm = HashFunction.fromName(hash.attributes['algo']! as String); hashValue = hash.innerText(); } @@ -144,7 +144,7 @@ class StickerPack { text: summary, ), constructHashElement( - hashAlgorithm.toName(), + hashAlgorithm, hashValue, ), @@ -193,7 +193,7 @@ class StickerPack { final hashes = List>.empty(growable: true); for (final hash in sticker.metadata.hashes.keys) { hashes.add([ - ...utf8.encode(hash), + ...utf8.encode(hash.toName()), 0x1f, ...utf8.encode(sticker.metadata.hashes[hash]!), 0x1f,