azure-protected-vm-secrets/SecretsProvsioningUT/SigningTests.cpp (176 lines of code) (raw):

#include "gtest/gtest.h" #ifdef PLATFORM_UNIX #include "Linux/OsslX509.h" #else #include "Windows/WincryptX509.h" #include "BcryptError.h" #endif // !PLATFORM_UNIX #include "JsonWebToken.h" #define JWT \ "eyJhbGciOiJSUzI1NiIsImtpZCI6IkRDMjc3NTMxQzgyQTJDNTRCQUE2MURGRTk4" \ "RTMxRjVBN0UyOUFFN0MiLCJ4NXQiOiIzQ2QxTWNncUxGUzZwaDMtbU9NZlduNHBy" \ "bnciLCJ0eXAiOiJKV1QiLCJ4NWMiOiJNSUlIZ3pDQ0JtdWdBd0lCQWdJVEhnVFFK" \ "aVQvdmc1V2hBaGtVZ0FBQk5BbUpEQU5CZ2txaGtpRzl3MEJBUXNGQURCRU1STXdF" \ "UVlLQ1pJbWlaUHlMR1FCR1JZRFIwSk1NUk13RVFZS0NaSW1pWlB5TEdRQkdSWURR" \ "VTFGTVJnd0ZnWURWUVFERXc5QlRVVWdTVzVtY21FZ1EwRWdNRFl3SGhjTk1qUXdO" \ "akkyTVRnME9UVXlXaGNOTWpVd05qSXhNVGcwT1RVeVdqQThNVG93T0FZRFZRUURF" \ "ekZsWVhOMGRYTXVZM1p0Y0hKdmRtbHphVzl1YVc1bmMyVnlkbWxqWlM1amIzSmxM" \ "bUY2ZFhKbExYUmxjM1F1Ym1WME1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NB" \ "UThBTUlJQkNnS0NBUUVBNkI1YnErb0pjaFZtWFFwRWxkcEMwVWdVemVqb0FvODQ1" \ "Q0ZVTUZQQTUwTVg4K3BMRTBwZkQ3TVlhQ2ZZYkQ3SUV2dkh5UVRCdHVWN0x6TWpi" \ "cW9DTkczWkNidUNhSDQ3QTVCZ0FxQjNXdVB2Tkc2NE96OEFGTkRDZlYyNVQ3K2ht" \ "OWFFMjRQVjBiVXRuTWo1WHBmQXJZLzcrWDZxVjV0djNtYlFETytwT2d4OUxIMWFq" \ "UHZCMTFsL25UUDZDNzVyUVozQkl4R0tBczZrWUxYdGZINFpwcVR0REMwcUIzVzQ1" \ "NWZVVG1ReFE4cVJtcHBVY0drNnd0MFRwRnJHT0w2QXh6MjJMRms0YkRYbUZKQXZS" \ "RFkzU1BnaVErZThlU2FtTVl3YTJibkJZQ0VxY3BNblEzMnJhQWZnVE02UzBrWlZS" \ "ZGdlZGxnMXEvN3lhdDBESEN1YTVRSURBUUFCbzRJRWREQ0NCSEF3SndZSkt3WUJC" \ "QUdDTnhVS0JCb3dHREFLQmdnckJnRUZCUWNEQVRBS0JnZ3JCZ0VGQlFjREFqQTlC" \ "Z2tyQmdFRUFZSTNGUWNFTURBdUJpWXJCZ0VFQVlJM0ZRaUdrT01OaE5XMGVJVHhp" \ "ejZGbTkwV3pwMFNnV0NDOWZZcmcvTFJJQUlCWkFJQkNqQ0NBY3NHQ0NzR0FRVUZC" \ "d0VCQklJQnZUQ0NBYmt3WXdZSUt3WUJCUVVITUFLR1YyaDBkSEE2THk5amNtd3Vi" \ "V2xqY205emIyWjBMbU52YlM5d2EybHBibVp5WVM5RFpYSjBjeTlDVERKUVMwbEpU" \ "bFJEUVRBeUxrRk5SUzVIUWt4ZlFVMUZKVEl3U1c1bWNtRWxNakJEUVNVeU1EQTJM" \ "bU55ZERCVEJnZ3JCZ0VGQlFjd0FvWkhhSFIwY0RvdkwyTnliREV1WVcxbExtZGli" \ "QzloYVdFdlFrd3lVRXRKU1U1VVEwRXdNaTVCVFVVdVIwSk1YMEZOUlNVeU1FbHVa" \ "bkpoSlRJd1EwRWxNakF3Tmk1amNuUXdVd1lJS3dZQkJRVUhNQUtHUjJoMGRIQTZM" \ "eTlqY213eUxtRnRaUzVuWW13dllXbGhMMEpNTWxCTFNVbE9WRU5CTURJdVFVMUZM" \ "a2RDVEY5QlRVVWxNakJKYm1aeVlTVXlNRU5CSlRJd01EWXVZM0owTUZNR0NDc0dB" \ "UVVGQnpBQ2hrZG9kSFJ3T2k4dlkzSnNNeTVoYldVdVoySnNMMkZwWVM5Q1RESlFT" \ "MGxKVGxSRFFUQXlMa0ZOUlM1SFFreGZRVTFGSlRJd1NXNW1jbUVsTWpCRFFTVXlN" \ "REEyTG1OeWREQlRCZ2dyQmdFRkJRY3dBb1pIYUhSMGNEb3ZMMk55YkRRdVlXMWxM" \ "bWRpYkM5aGFXRXZRa3d5VUV0SlNVNVVRMEV3TWk1QlRVVXVSMEpNWDBGTlJTVXlN" \ "RWx1Wm5KaEpUSXdRMEVsTWpBd05pNWpjblF3SFFZRFZSME9CQllFRkYyV0FJYzR1" \ "c1RkR3QvcWorZytUc2UxaGVZdE1BNEdBMVVkRHdFQi93UUVBd0lGb0RDQ0FTWUdB" \ "MVVkSHdTQ0FSMHdnZ0VaTUlJQkZhQ0NBUkdnZ2dFTmhqOW9kSFJ3T2k4dlkzSnNM" \ "bTFwWTNKdmMyOW1kQzVqYjIwdmNHdHBhVzVtY21FdlExSk1MMEZOUlNVeU1FbHVa" \ "bkpoSlRJd1EwRWxNakF3Tmk1amNteUdNV2gwZEhBNkx5OWpjbXd4TG1GdFpTNW5Z" \ "bXd2WTNKc0wwRk5SU1V5TUVsdVpuSmhKVEl3UTBFbE1qQXdOaTVqY215R01XaDBk" \ "SEE2THk5amNtd3lMbUZ0WlM1blltd3ZZM0pzTDBGTlJTVXlNRWx1Wm5KaEpUSXdR" \ "MEVsTWpBd05pNWpjbXlHTVdoMGRIQTZMeTlqY213ekxtRnRaUzVuWW13dlkzSnNM" \ "MEZOUlNVeU1FbHVabkpoSlRJd1EwRWxNakF3Tmk1amNteUdNV2gwZEhBNkx5OWpj" \ "bXcwTG1GdFpTNW5ZbXd2WTNKc0wwRk5SU1V5TUVsdVpuSmhKVEl3UTBFbE1qQXdO" \ "aTVqY213d2daMEdBMVVkSUFTQmxUQ0JrakFNQmdvckJnRUVBWUkzZXdFQk1HWUdD" \ "aXNHQVFRQmdqZDdBZ013V0RCV0JnZ3JCZ0VGQlFjQ0FqQktIa2dBTndBeUFHWUFP" \ "UUE0QURnQVlnQm1BQzBBT0FBMkFHWUFNUUF0QURRQU1RQmhBR1lBTFFBNUFERUFZ" \ "UUJpQUMwQU1nQmtBRGNBWXdCa0FEQUFNUUF4QUdRQVlnQTBBRGN3REFZS0t3WUJC" \ "QUdDTjNzREFUQU1CZ29yQmdFRUFZSTNld1FCTUI4R0ExVWRJd1FZTUJhQUZQRkdh" \ "TWJ4dy9BckxYMkxhdUd5K2I0MS9ORkJNQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZC" \ "d01CQmdnckJnRUZCUWNEQWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQXhHWThY" \ "cmkrR0FQZGk1QVpBYVpvdGNlbEJqcnFzZ2VZSlhDb1RqRDVVWVdiaDRxY3hDVXI1" \ "ZCtRQk5pMkJNdWZpWHFHeldkdndlVWZSUWhQQko0TUFSL204T3pTdGR0LzhXQTdL" \ "YXUzbW4ySUZldGFraitJUGQvNmFyTW5ueWVOUXB1UmNSYThrT1BjOXVvRVEzTmk4" \ "ZUNnY2c2YXNvbEp2NFlRaE4yNGpyam9yTXBpRE5KUFZWTm4zQU1ITHFkUk9CMHBY" \ "NWpYd1RVR0V4eTdreTBEaU5IL2FBSUtsTTVoVGp1UmIwTGNSSXJUNXhJeWowRVhj" \ "d2VRSWhXbkdqcCtqazBXT3dZMmYyZjhEdUlaT1pLS0hkKytSNWRpU29EcXAzdnpZ" \ "VlhHU01XY2dVNzFuWDRCbTJPSTdOdjByZUNmVWc3aDFuTG5tbXcxSUFnalpTUzBL" \ "Zz09In0.eyJlbmNyeXB0ZWRTZWNyZXQiOiJnSnpFRVRQZEZoTHFWNzlHS3IycVVB" \ "bis3ajZHT0V2aWZHSmVpZjVjNW5zc1BHWWRLREZzYktaZDVRc1NaNjA9IiwiZXBo" \ "ZW1lcmFsRWNkaFB1YmxpY0tleSI6Ik1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpq" \ "MERBUWNEUWdBRVh2QzhRbEhiOEtETEJsWG84ZmJRR29Ra1lBcHdCeVhqbkRicita" \ "aVUzTjJudTZoMnJYOEl4MmZpVWVjbU05QXBObElwRzlxbHZobVE5aU5nVFlmMFpR" \ "PT0iLCJlbmNyeXB0ZWRHdWVzdEVjZGhQcml2YXRlS2V5IjoiWkFvVnIrb2JiazNZ" \ "a0RrQ1BTVFZoMjYwVEFnRjk4dDk0K1RyMHpJUkp0Tk1UczJ6SnZKMTZhVmN6RFB2" \ "Sy80N2lGWU9pM014ME9oaUJabzFZcEVpcmk4aER2cHVScVNIK2VaZXU5OUVUTXVB" \ "emlQeU55di9FM2hJcnFOR25kSnhOK1JIZStqeHdJcVNObTBqaUhETU9NeEVqeUpo" \ "amJaZVNJZ0c1VTBKWmdrWFpZQlFOWitCbjNiMTIwL2YwK2lGQ2tOWTlPbk1WS0ZY" \ "MGc9PSIsIndyYXBwZWRBZXNUcmFuc3BvcnRLZXkiOiJCQy9WRGxVRG5pZGpzLzdE" \ "dEt4UEdWNWNndDNjeHR5TlBvcTZvMVFtcTl5d01RS01lOHRSdnZYMWd0d1AzVEZP" \ "bm15VC80aXh1TTFEcEczN0lyODRiMlQ3Zmw0cCsyTFUreFp3WVp5ditDa3JKV1Zk" \ "OFNlVTdLT2h1cEdxVVRlV0Vtb3QxRERtcWhtczRJVktwbCtrbloyOUl2TlUzb2xm" \ "dVcvSnBqbVZsZlJUK3BNRTkySUNGNlJQS2JqMVRabGpQY3pVSEc5NDYweEltYnVM" \ "SkVkdkIrZ0t0YkpySk1iSzEyYUxZL0EvRzRrNC9KVTJBK1UvaUJkNzdsNWF0cHha" \ "ZUkxSFJLOXJZSFZlQXRVb1N6MTMxeGs0akdoZUxZL0dJQ3p4RDhYWVdKYmp0SkJt" \ "SlIydTZaelZtNk9KZ1hzNUxIQmViYnNQRERJaVV4dTlKUmJWWXc9PSIsImRhdGFO" \ "b25jZSI6IkJTb2w2NjQ3YVo0VGVkcXciLCJrZXlOb25jZSI6ImVrZUhObFg0Ylhv" \ "RGxOeW4iLCJzYWx0IjoiVG56ZzQxYTVOUURUYjRLMHM5dDlCMEw3VFJnM0daRERh" \ "QVhGS3EycnFYaz0iLCJuYmYiOjE3MjA3MzUwMDUsImV4cCI6MTcyMDczNjgwNSwi" \ "aWF0IjoxNzIwNzM1MDA1fQ.R3brmL-6AeDWG3FqYH7OckpMkplkucmuRFJOFT731" \ "NxSmD1g8Leldyy4tnwxoEHXF1ZEpupgDvVf3eg1uUYuWd3GzVAX7H_hl8pT7KQEF" \ "52L6iSAKrCkZvKiqXAI9dsSf6EKPPSvMao7w6Zjo9WdbS-3cl3gsxzb7v0BOX4PS" \ "Eb9BQVA7qeRqIhqXul1-7EY1WGH4dO4_TRZsc1Seb47qVg-wlkT118FN5eW5hVSE" \ "sJam_22bjLobc2vox-oBzVwp7KxVmfnShWltBqHvTZ9p4V4pzKaewdGgTv9IHKI-" \ "VwgMeGHQAOQG_EcG1A6Q24tNmdIz0pfCSWY-MIilqa-8Q" TEST(X509Tests, LoadCertificate) { // Test that the LoadCertificate function loads the certificate correctly std::unique_ptr<JsonWebToken> jwt = std::make_unique<JsonWebToken>(); jwt->ParseToken(JWT, true); std::string cert_str = jwt->getHeader()["x5c"]; std::vector<unsigned char> cert = encoders::base64_decode(cert_str); #ifdef PLATFORM_UNIX std::unique_ptr<OsslX509> x509 = std::make_unique<OsslX509>(); #else std::unique_ptr<WincryptX509> x509 = std::make_unique<WincryptX509>(); #endif // !PLATFORM_UNIX std::for_each(std::begin(INTERMEDIATE_CERTS), std::end(INTERMEDIATE_CERTS), [&](const auto cert) { x509->LoadIntermediateCertificate(cert); } ); x509->LoadLeafCertificate(cert_str.c_str()); bool result = x509->VerifyCertChain(); EXPECT_TRUE(result); } TEST(X509Tests, ValidateSignature) { // Test that the VerifySignature function correctly verifies a signature std::unique_ptr<JsonWebToken> jwt = std::make_unique<JsonWebToken>(); jwt->ParseToken(JWT, true); std::string cert_str = jwt->getHeader()["x5c"]; std::vector<unsigned char> cert = encoders::base64_decode(cert_str); std::string str_jwt = std::string(JWT); std::string signed_prtion = str_jwt.substr(0, str_jwt.find_last_of('.')); #ifdef PLATFORM_UNIX std::unique_ptr<OsslX509> x509 = std::make_unique<OsslX509>(); #else std::unique_ptr<WincryptX509> x509 = std::make_unique<WincryptX509>(); #endif // !PLATFORM_UNIX std::for_each(std::begin(INTERMEDIATE_CERTS), std::end(INTERMEDIATE_CERTS), [&](const auto cert) { x509->LoadIntermediateCertificate(cert); } ); x509->LoadLeafCertificate(cert_str.c_str()); bool result = x509->VerifyCertChain(); EXPECT_TRUE(result); std::vector<unsigned char> signed_data(signed_prtion.begin(), signed_prtion.end()); result = x509->VerifySignature(signed_data, jwt->getSignature()); EXPECT_TRUE(result); } TEST(X509Tests, FailValidateSignature) { // Test that the VerifySignature function handles an invalid signature properly std::unique_ptr<JsonWebToken> jwt = std::make_unique<JsonWebToken>(); jwt->ParseToken(JWT, false); std::string cert_str = jwt->getHeader()["x5c"]; std::vector<unsigned char> cert = encoders::base64_decode(cert_str); // Modify jwt jwt->addClaim("dataNonce", encoders::base64_encode(std::vector<unsigned char>(32, 0))); std::string str_jwt = jwt->CreateToken(); std::string signed_prtion = str_jwt.substr(0, str_jwt.find_last_of('.')); #ifdef PLATFORM_UNIX std::unique_ptr<OsslX509> x509 = std::make_unique<OsslX509>(); #else std::unique_ptr<WincryptX509> x509 = std::make_unique<WincryptX509>(); #endif // !PLATFORM_UNIX std::for_each(std::begin(INTERMEDIATE_CERTS), std::end(INTERMEDIATE_CERTS), [&](const auto cert) { x509->LoadIntermediateCertificate(cert); } ); x509->LoadLeafCertificate(cert_str.c_str()); bool result = x509->VerifyCertChain(); EXPECT_TRUE(result); std::vector<unsigned char> signed_data(signed_prtion.begin(), signed_prtion.end()); #ifndef PLATFORM_UNIX EXPECT_THROW({ // We expect this to throw an error of invalid signature result = x509->VerifySignature(signed_data, jwt->getSignature()); }, BcryptError ); #else // We expect this to return false for invalid signature result = x509->VerifySignature(signed_data, jwt->getSignature()); ASSERT_FALSE(result); #endif // !PLATFORM_UNIX } #ifdef PLATFORM_UNIX TEST(X509Tests, CertGen) { // Test that the LoadCertificate function loads the certificate correctly std::unique_ptr<OsslX509> certChain; std::vector<unsigned char> testData = { 0x01, 0x02, 0x03, 0x04, 0x05 }; std::vector<unsigned char> badData = { 0x05, 0x04, 0x03, 0x02, 0x01 }; std::vector<unsigned char> signature; try { certChain = generateCertChain(); signature = certChain->SignData(testData); } catch (std::exception& e) { std::cout << e.what() << std::endl; } EXPECT_TRUE(certChain->VerifyCertChain()); EXPECT_TRUE(certChain->VerifySignature(testData, signature)); EXPECT_FALSE(certChain->VerifySignature(badData, signature)); } #endif // PLATFORM_UNIX