[Libreoffice-commits] online.git: wsd/ProofKey.cpp
Mike Kaganski (via logerrit)
logerrit at kemper.freedesktop.org
Wed Feb 19 09:20:16 UTC 2020
wsd/ProofKey.cpp | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
New commits:
commit 6eda59123a8fc1d237a25468244118219497bf5e
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Tue Feb 18 23:46:46 2020 +0300
Commit: Mike Kaganski <mike.kaganski at 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 <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Mike Kaganski <mike.kaganski at 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;
}
More information about the Libreoffice-commits
mailing list