2020-04-07 15:42:30 -05:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
2020-04-08 15:15:04 -05:00
*
* Uses known - good sample data from :
* https : //github.com/microsoft/Office-Online-Test-Tools-and-Documentation
2020-04-07 15:42:30 -05:00
*/
# include <config.h>
# include <test/lokassert.hpp>
# include <ProofKey.hpp>
2020-04-08 15:15:04 -05:00
# include <Poco/Crypto/RSAKey.h>
# include <Poco/Crypto/DigestEngine.h>
2020-04-07 15:42:30 -05:00
# include <Util.hpp>
2020-04-08 15:15:04 -05:00
# include <openssl/bn.h>
# include <openssl/pem.h>
# include <openssl/buffer.h>
2020-04-08 15:39:54 -05:00
# include <openssl/opensslv.h>
2020-04-08 15:15:04 -05:00
2020-04-07 15:42:30 -05:00
/// Delta unit-tests.
class WopiProofTests : public CPPUNIT_NS : : TestFixture
{
CPPUNIT_TEST_SUITE ( WopiProofTests ) ;
2020-04-08 12:25:44 -05:00
CPPUNIT_TEST ( testCapiBlob ) ;
2020-04-08 15:15:04 -05:00
CPPUNIT_TEST ( testExistingProof ) ;
2020-04-08 15:39:54 -05:00
CPPUNIT_TEST ( testOurProof ) ;
2020-04-07 15:42:30 -05:00
CPPUNIT_TEST_SUITE_END ( ) ;
2020-04-08 12:25:44 -05:00
void testCapiBlob ( ) ;
2020-04-08 15:15:04 -05:00
void testExistingProof ( ) ;
2020-04-08 15:39:54 -05:00
void testOurProof ( ) ;
2020-04-08 12:25:44 -05:00
2020-04-08 15:15:04 -05:00
BIGNUM * Base64ToNum ( const std : : string & str )
{
std : : vector < unsigned char > vec = Proof : : Base64ToBytes ( str ) ;
return BN_bin2bn ( & vec [ 0 ] , vec . size ( ) , nullptr ) ;
}
2020-04-08 15:39:54 -05:00
void verifySignature ( const std : : string & access ,
const std : : string & uri ,
2020-04-09 02:01:41 -05:00
int64_t ticks ,
2020-04-08 15:39:54 -05:00
const std : : string & discoveryModulus ,
const std : : string & discoveryExponent ,
const std : : string & msgProof ) ;
2020-04-07 15:42:30 -05:00
} ;
2020-04-08 12:25:44 -05:00
void WopiProofTests : : testCapiBlob ( )
{
std : : vector < unsigned char > modulus = Proof : : Base64ToBytes ( " 0HOWUPFFgmSYHbLZZzdWO/HUOr8YNfx5NAl7GUytooHZ7B9QxQKTJpj0NIJ4XEskQW8e4dLzRrPbNOOJ+KpWHttXz8HoQXkkZV/gYNxaNHJ8/pRXGMZzfVM5vchhx/2C7ULPTrpBsSpmfWQ6ShaVoQzfThFUd0MsBvIN7HVtqzPx9jbSV04wAqyNjcro7F3iu9w7AEsMejHbFlWoN+J05dP5ixryF7+2U5RVmjMt7/dYUdCoiXvCMt2CaVr0XEG6udHU4iDKVKZjmUBc7cTWRzhqEL7lZ1yQfylp38Nd2xxVJ0sSU7OkC1bBDlePcYGaF3JjJgsmp/H5BNnlW9gSxQ== " ) ;
std : : vector < unsigned char > exponent = Proof : : Base64ToBytes ( " AQAB " ) ;
std : : vector < unsigned char > capiBlob = Proof : : RSA2CapiBlob ( modulus , exponent ) ;
std : : string capiEncoded = Proof : : BytesToBase64 ( capiBlob ) ;
LOK_ASSERT_EQUAL ( capiEncoded , std : : string ( " BgIAAACkAABSU0ExAAgAAAEAAQDFEthb5dkE+fGnJgsmY3IXmoFxj1cOwVYLpLNTEksnVRzbXcPfaSl/kFxn5b4QajhH1sTtXECZY6ZUyiDi1NG5ukFc9Fppgt0ywnuJqNBRWPfvLTOaVZRTtr8X8hqL+dPldOI3qFUW2zF6DEsAO9y74l3s6MqNjawCME5X0jb28TOrbXXsDfIGLEN3VBFO3wyhlRZKOmR9ZiqxQbpOz0Ltgv3HYci9OVN9c8YYV5T+fHI0Wtxg4F9lJHlB6MHPV9seVqr4ieM027NG89LhHm9BJEtceII09JgmkwLFUB/s2YGirUwZewk0efw1GL861PE7Vjdn2bIdmGSCRfFQlnPQ " ) ) ;
}
2020-04-08 15:39:54 -05:00
void WopiProofTests : : verifySignature ( const std : : string & access ,
const std : : string & uri ,
2020-04-09 02:01:41 -05:00
int64_t ticks ,
2020-04-08 15:39:54 -05:00
const std : : string & discoveryModulus ,
const std : : string & discoveryExponent ,
const std : : string & msgProofStr )
2020-04-07 15:42:30 -05:00
{
2020-04-08 15:39:54 -05:00
# if OPENSSL_VERSION_NUMBER > 0x10100000L
std : : vector < unsigned char > proof = Proof : : GetProof ( access , uri , ticks ) ;
2020-04-08 15:15:04 -05:00
2020-04-08 15:39:54 -05:00
BIGNUM * modulus = Base64ToNum ( discoveryModulus ) ;
BIGNUM * exponent = Base64ToNum ( discoveryExponent ) ;
2020-04-08 15:15:04 -05:00
RSA * rsa = RSA_new ( ) ;
LOK_ASSERT ( rsa ! = nullptr ) ;
LOK_ASSERT_EQUAL ( 1 , RSA_set0_key ( rsa , modulus , exponent , nullptr ) ) ;
2020-04-08 15:39:54 -05:00
std : : vector < unsigned char > msgProof = Proof : : Base64ToBytes ( msgProofStr ) ;
2020-04-08 15:15:04 -05:00
Poco : : Crypto : : DigestEngine digestEngine ( " SHA256 " ) ;
digestEngine . update ( proof . data ( ) , proof . size ( ) ) ;
std : : vector < unsigned char > digest = digestEngine . digest ( ) ;
2020-04-09 02:01:41 -05:00
LOK_ASSERT_EQUAL ( 1 , RSA_verify ( digestEngine . nid ( ) ,
2020-04-08 15:15:04 -05:00
& digest [ 0 ] , digest . size ( ) ,
& msgProof [ 0 ] , msgProof . size ( ) ,
rsa ) ) ;
RSA_free ( rsa ) ;
2020-04-08 15:39:54 -05:00
# else
( void ) access ; ( void ) uri ; ( void ) ticks ;
( void ) discoveryModulus ; ( void ) discoveryExponent ;
( void ) msgProofStr ;
std : : cerr < < " OpenSSL too old to verify keys easily " < < OPENSSL_VERSION_TEXT < < " needs to be 1.1.0 at least \n " ;
# endif
}
void WopiProofTests : : testExistingProof ( )
{
verifySignature (
" yZhdN1qgywcOQWhyEMVpB6NE3pvBksvcLXsrFKXNtBeDTPW%2fu62g2t%2fOCWSlb3jUGaz1zc%2fzOzbNgAredLdhQI1Q7sPPqUv2owO78olmN74DV%2fv52OZIkBG%2b8jqjwmUobcjXVIC1BG9g%2fynMN0itZklL2x27Z2imCF6xELcQUuGdkoXBj%2bI%2bTlKM " , // access token
" https://contoso.com/wopi/files/vHxYyRGM8VfmSGwGYDBMIQPzuE+sSC6kw+zWZw2Nyg?access_token=yZhdN1qgywcOQWhyEMVpB6NE3pvBksvcLXsrFKXNtBeDTPW%2fu62g2t%2fOCWSlb3jUGaz1zc%2fzOzbNgAredLdhQI1Q7sPPqUv2owO78olmN74DV%2fv52OZIkBG%2b8jqjwmUobcjXVIC1BG9g%2fynMN0itZklL2x27Z2imCF6xELcQUuGdkoXBj%2bI%2bTlKM " , // uri
2020-04-09 02:01:41 -05:00
INT64_C ( 635655897610773532 ) , // ticks
2020-04-08 15:39:54 -05:00
" 0HOWUPFFgmSYHbLZZzdWO/HUOr8YNfx5NAl7GUytooHZ7B9QxQKTJpj0NIJ4XEskQW8e4dLzRrPbNOOJ+KpWHttXz8HoQXkkZV/gYNxaNHJ8/pRXGMZzfVM5vchhx/2C7ULPTrpBsSpmfWQ6ShaVoQzfThFUd0MsBvIN7HVtqzPx9jbSV04wAqyNjcro7F3iu9w7AEsMejHbFlWoN+J05dP5ixryF7+2U5RVmjMt7/dYUdCoiXvCMt2CaVr0XEG6udHU4iDKVKZjmUBc7cTWRzhqEL7lZ1yQfylp38Nd2xxVJ0sSU7OkC1bBDlePcYGaF3JjJgsmp/H5BNnlW9gSxQ== " , // modulus
" AQAB " , // exponent
" IflL8OWCOCmws5qnDD5kYMraMGI3o+T+hojoDREbjZSkxbbx7XIS1Av85lohPKjyksocpeVwqEYm9nVWfnq05uhDNGp2MsNyhPO9unZ6w25Rjs1hDFM0dmvYx8wlQBNZ/CFPaz3inCMaaP4PtU85YepaDccAjNc1gikdy3kSMeG1XZuaDixHvMKzF/60DMfLMBIu5xP4Nt8i8Gi2oZs4REuxi6yxOv2vQJQ5+8Wu2Olm8qZvT4FEIQT9oZAXebn/CxyvyQv+RVpoU2gb4BreXAdfKthWF67GpJyhr+ibEVDoIIolUvviycyEtjsaEBpOf6Ne/OLRNu98un7WNDzMTQ== " ) ; // message proof
}
void WopiProofTests : : testOurProof ( )
{
Proof gen ( Proof : : Type : : CreateKey ) ;
const VecOfStringPairs & discovery = gen . GetProofKeyAttributes ( ) ;
int len = discovery . size ( ) ;
LOK_ASSERT_EQUAL ( 3 , len ) ;
LOK_ASSERT_EQUAL ( discovery [ 0 ] . first , std : : string ( " value " ) ) ;
LOK_ASSERT_EQUAL ( discovery [ 1 ] . first , std : : string ( " modulus " ) ) ;
std : : string modulus = discovery [ 1 ] . second ;
LOK_ASSERT_EQUAL ( discovery [ 2 ] . first , std : : string ( " exponent " ) ) ;
std : : string exponent = discovery [ 2 ] . second ;
std : : string access_token = " !££$%£^$-!---~@@{}OP " ;
std : : string uri = " https://user@short.com:12345/blah?query_string=foo " ;
VecOfStringPairs pairs = gen . GetProofHeaders ( access_token , uri ) ;
len = pairs . size ( ) ;
LOK_ASSERT_EQUAL ( 2 , len ) ;
LOK_ASSERT_EQUAL ( pairs [ 0 ] . first , std : : string ( " X-WOPI-TimeStamp " ) ) ;
std : : string timestamp = pairs [ 0 ] . second ;
LOK_ASSERT_EQUAL ( pairs [ 1 ] . first , std : : string ( " X-WOPI-Proof " ) ) ;
std : : string proof = pairs [ 1 ] . second ;
2020-04-09 02:01:41 -05:00
int64_t ticks = std : : stoll ( timestamp . c_str ( ) , nullptr , 10 ) ;
2020-04-08 15:39:54 -05:00
verifySignature ( access_token , uri , ticks , modulus , exponent , proof ) ;
2020-07-02 02:54:59 -05:00
// tdf#134041: test another data
access_token = " ~!@#$%^&*()_+`1234567890-= " ;
uri = " https://user2@short.com:12345/blah?query_string=bar " ;
pairs = gen . GetProofHeaders ( access_token , uri ) ;
len = pairs . size ( ) ;
LOK_ASSERT_EQUAL ( 2 , len ) ;
LOK_ASSERT_EQUAL ( pairs [ 0 ] . first , std : : string ( " X-WOPI-TimeStamp " ) ) ;
timestamp = pairs [ 0 ] . second ;
LOK_ASSERT_EQUAL ( pairs [ 1 ] . first , std : : string ( " X-WOPI-Proof " ) ) ;
proof = pairs [ 1 ] . second ;
ticks = std : : stoll ( timestamp . c_str ( ) , nullptr , 10 ) ;
verifySignature ( access_token , uri , ticks , modulus , exponent , proof ) ;
2020-04-07 15:42:30 -05:00
}
CPPUNIT_TEST_SUITE_REGISTRATION ( WopiProofTests ) ;
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */