wsd/ProofKey.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
New commits: commit 6eda59123a8fc1d237a25468244118219497bf5e Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Tue Feb 18 23:46:46 2020 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Wed Feb 19 10:19:55 2020 +0100 Proof key: make sure public exponent is exactly 4 bytes It seems that Poco returns 3-byte public exponent (0x010001) as 3-element vector, and MS CAPI blob must include 4-byte exponent In Poco code (Crypto/src/RSAKeyImpl.cpp), its convertToByteVec uses OpenSSL's BN_bn2bin, which returns big-endian byte order (see OpenSSL's crypto/bn/bn_lib.c). That is returned from Poco's RSAKey::modulus() and RSAKey::*Exponent() unchanged, so treat them accordingly. Change-Id: I37f5fb9a310d42c7f346429c39611b25dd5bba2f Reviewed-on: https://gerrit.libreoffice.org/c/online/+/88989 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/wsd/ProofKey.cpp b/wsd/ProofKey.cpp index fa6dd6bd0..e0dba1b46 100644 --- a/wsd/ProofKey.cpp +++ b/wsd/ProofKey.cpp @@ -37,6 +37,7 @@ #include <Poco/URI.h> #include <Poco/Util/Application.h> +#include "Exceptions.hpp" #include <Log.hpp> #include <Util.hpp> @@ -102,7 +103,7 @@ public: private: static std::string ProofKeyPath(); - // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-mqqb/ade9efde-3ec8-4e47-9ae9-34b64d8081bb + // modulus and exponent are big-endian vectors static std::vector<unsigned char> RSA2CapiBlob(const std::vector<unsigned char>& modulus, const std::vector<unsigned char>& exponent); @@ -174,9 +175,17 @@ std::string Proof::ProofKeyPath() return keyPath; } +// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-mqqb/ade9efde-3ec8-4e47-9ae9-34b64d8081bb std::vector<unsigned char> Proof::RSA2CapiBlob(const std::vector<unsigned char>& modulus, const std::vector<unsigned char>& exponent) { + // Exponent might have arbitrary length in OpenSSL; we need exactly 4 + if (exponent.size() > 4) + throw ParseError("Proof key public exponent is longer than 4 bytes."); + // make sure exponent length is correct; assume we are passed big-endian vectors + std::vector<unsigned char> exponent32LE(4); + std::copy(exponent.rbegin(), exponent.rend(), exponent32LE.begin()); + std::vector<unsigned char> capiBlob = { 0x06, 0x02, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, @@ -184,11 +193,11 @@ std::vector<unsigned char> Proof::RSA2CapiBlob(const std::vector<unsigned char>& }; // modulus size in bits - 4 bytes (little-endian) const auto bitLen = ToLEBytes<std::uint32_t>(modulus.size() * 8); - capiBlob.reserve(capiBlob.size() + bitLen.size() + exponent.size() + modulus.size()); + capiBlob.reserve(capiBlob.size() + bitLen.size() + exponent32LE.size() + modulus.size()); std::copy(bitLen.begin(), bitLen.end(), std::back_inserter(capiBlob)); // exponent - 4 bytes (little-endian) - std::copy(exponent.rbegin(), exponent.rend(), std::back_inserter(capiBlob)); - // modulus (little-endian) + std::copy(exponent32LE.begin(), exponent32LE.end(), std::back_inserter(capiBlob)); + // modulus (passed big-endian, stored little-endian) std::copy(modulus.rbegin(), modulus.rend(), std::back_inserter(capiBlob)); return capiBlob; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits