Files
ce_cdm/core/test/fake_provisioning_server.cpp
2020-04-10 16:13:07 -07:00

363 lines
21 KiB
C++

// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "fake_provisioning_server.h"
#include "core_message_deserialize.h"
#include "core_message_serialize.h"
#include "core_message_serialize_proto.h"
#include "crypto_session.h"
#include "license_protocol.pb.h"
#include "log.h"
#include "oec_session_util.h"
#include "oec_test_data.h"
#include "privacy_crypto.h"
#include "service_certificate.h"
#include "string_conversions.h"
// TODO: refactor oec_session so that these are not needed.
#include <gtest/gtest.h>
#include <openssl/aes.h>
#include <openssl/bio.h>
#include <openssl/cmac.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <stdint.h>
namespace wvcdm {
namespace {
// This is a sample RSA private key, it pairs with the public fake service
// certificate below.
// From file test_rsa_key_2_carmichael.pk8 in team shared drive. Size is 1216.
const std::string kPrivateKeyFakeServiceCert = a2bs_hex(
"308204bc020100300d06092a864886f70d0101010500048204a6308204a2020100028201"
"0100a700366065dcbd545a2a40b4e1159458114f9458dddea71f3c2ce08809296157675e"
"567eee278f59349a2aaa9db44efaa76ad4c97a53c14e9fe334f73db7c910474f28da3fce"
"317bfd0610ebf7be92f9affb3e68daee1a644cf329f2739e39d8f66fd8b28082718eb5a4"
"f2c23ecd0acab604cd9a138b54735425548cbe987a67addab34eb3fa82a84a6798565754"
"71cd127feda301c06a8b24039688be97662abc53c98306515a88651318e43aed6bf1615b"
"4cc81ef4c2ae085e2d5ff8127fa2fcbb211830dafe40fb01ca2e370ecedd768782460b3a"
"778fc072072c7f9d1e865bed2729df039762ef44d35b3ddb9c5e1b7b39b40b6d046bbbbb"
"2c5fcfb37a050203010001028201000af94a1972881b4ed82fef999332da51212e1406f4"
"e9651cf9d4cf1a5153cd48338c30eddd536f2982f9e074deb11301888fce14c13b90b7cc"
"6cdf35a1f21a3dbe19d70ae46775bbfa87f403b57f69e40b6adc928254641a942de46340"
"b2b4856bc834baa21430471aeb906230434402c70c30c07fa947aede682792aa1195f56f"
"fc198b49a0779dc6135d73ff45a24c3bf3e12dd7c470e26c37994c7aa927f83ad6fdc5d8"
"fa2d0e714b857ececb1c7971bdff63036b5868e014ca5e85fdd0b7e06814ff2c8222268a"
"3fbfb02a90ffc772fc66513e519f82680ef3657488abb7e5975f0f3ee53abca4a150dd5c"
"944b0c7071484ed0ec468fdfa29afed8351a2f02818100cf738cbe6d452d0c0b5d5c6c75"
"78cc3548b698f1b964608c43eb85ab04b67d1b717506e2da84682e7f4ce373b4de514bb6"
"51867bd0e64df3d1cf1afe7f3a83bab3e1ff541393d79c2780b71e649ef7322b4629f7f8"
"186cf74abe4bee96908fa216226acc48067463437f2722443c2d3b62f11cb42733852660"
"4816cbeff8cd3702818100ce15436e4b0ff93f87c3414597b149c2192387e4241c64e528"
"cb431014140e19cbbbdbfd119d1768786d6170633aa1b3f3a75b0effb76111549199e591"
"322deb3fd83ef7d4cbd2a341c1eec69213eb7f4258f4d0b2741d8e8746cd14b816adb5bd"
"0d6c955a16bfe953dafbed835167a955ab54029520a6681753a8ea43e5b0a3028180679c"
"32833957ff73b089648bd6f00a2de2af301c2a97f3909aab9b0b1b4379a0a73de7be8d9c"
"ebdbad40dda90080b8e1b3a16c2592e433b2beeb4d74265f37439c6c17760a812082a148"
"2c2d45dc0f624332bbeb5941f9ca58ce4a665354c828101e087116d802714158d456ccf5"
"b131a3ed008509bf3595412940198335246902818055100bcc3ba9753d16e1ae50766394"
"494cad10cb47687cf0e5dcb86aab8ef79f082c1b8aa2b98fceec5e61a8cd1c87604ac31a"
"5fdf8726c6cb7c69e48b01065922fa344b81873c036d020a77e615d8cfa768266cfa2bd9"
"835a2d0c3b701cd448bea70ad9bedcc30c2133b366ff1c1bc89676e86f4474bc9b1c7dc8"
"ac21a86e370281802c7cad1e75f6691de7a6ca747d67c8652866c443a6bd4057aeb7652c"
"52f9e4c7817b56a3d20de83370cf0684b34e4450756196864bb62badf0ad57d0370d1d35"
"50cb69223929b93ad329230260f7ab3040da8e4d457026f4a20dd0645d473c18f4d45295"
"00ae846b47b23c82d37253de722cf7c12236d91856fe392833e0db03");
// This is a fake service certificate.
// From the team shared drive file
// oem-7913-leaf-and-intermediate-certs-test-key-2-carmichael.p7b, size 2353.
const std::string kPublicFakeServiceCert = a2bs_hex(
"3082092d06092a864886f70d010702a082091e3082091a0201013100300f06092a864886"
"f70d010701a0020400a08208fe3082037130820259a003020102021100c28d2022828b9e"
"639d15892ca98fd95d300d06092a864886f70d01010b0500306b310b3009060355040613"
"025553310b300906035504080c0257413111300f06035504070c084b69726b6c616e6431"
"0f300d060355040a0c06476f6f676c653111300f060355040b0c085769646576696e6531"
"18301606035504030c0f73797374656d2069643a2037393133301e170d31383031313131"
"33323632325a170d3338303130363133323632325a30653112301006035504030c093739"
"31332d6c656166310b3009060355040613025553310b300906035504080c025741311130"
"0f06035504070c084b69726b6c616e64310f300d060355040a0c06476f6f676c65311130"
"0f060355040b0c085769646576696e6530820122300d06092a864886f70d010101050003"
"82010f003082010a0282010100a700366065dcbd545a2a40b4e1159458114f9458dddea7"
"1f3c2ce08809296157675e567eee278f59349a2aaa9db44efaa76ad4c97a53c14e9fe334"
"f73db7c910474f28da3fce317bfd0610ebf7be92f9affb3e68daee1a644cf329f2739e39"
"d8f66fd8b28082718eb5a4f2c23ecd0acab604cd9a138b54735425548cbe987a67addab3"
"4eb3fa82a84a679856575471cd127feda301c06a8b24039688be97662abc53c98306515a"
"88651318e43aed6bf1615b4cc81ef4c2ae085e2d5ff8127fa2fcbb211830dafe40fb01ca"
"2e370ecedd768782460b3a778fc072072c7f9d1e865bed2729df039762ef44d35b3ddb9c"
"5e1b7b39b40b6d046bbbbb2c5fcfb37a050203010001a31630143012060a2b06010401d6"
"79040101040402021ee9300d06092a864886f70d01010b050003820101008895eccd8ba7"
"51da7481a539621a0e2ede3c37eaad7cee9b268ee2d634cdb770babfa0a3feb34bbcf41c"
"726681d50933780c6121a8f1e2c9e283c21902f2e8ab17363a0b20af0fae2e7368ac15ee"
"9cc092037e9563aaad159643203be59b1fca02baf0077680d7a31aebc8db037b4356e596"
"6b86fe08588a84bde94718eeb2a8057bf0fdaab985cd7a0e6b6c9fc675d22afe5bf3b731"
"6cace3009fe7dde381c136c31c5fdff2c35efa5532d85ca8e5ccb64ae9e2cc3844074659"
"348479f9ee3c4b4890ab73b0a192c3d6838781ca1281d65df76f7a355e4f02668a478882"
"abf0121db9753b7ba83615efa8120e53b4837853c052aea60aa053dc1c1522dd17983082"
"05853082036da003020102021003b1f758df1de325000b103dd5e6e464300d06092a8648"
"86f70d01010b0500307e310b30090603550406130255533113301106035504080c0a5761"
"7368696e67746f6e3111300f06035504070c084b69726b6c616e64310f300d060355040a"
"0c06476f6f676c653111300f060355040b0c085769646576696e65312330210603550403"
"0c1a7769646576696e652e636f6d2f6f656d2d726f6f742d70726f64301e170d31373131"
"31383031313333355a170d3237313131383031313331335a306b310b3009060355040613"
"025553310b300906035504080c0257413111300f06035504070c084b69726b6c616e6431"
"0f300d060355040a0c06476f6f676c653111300f060355040b0c085769646576696e6531"
"18301606035504030c0f73797374656d2069643a203739313330820122300d06092a8648"
"86f70d01010105000382010f003082010a0282010100aec871ae080c06062d817ca98bb3"
"d666e4f6085e5a75e874617a88ca85140d58a409196c60c9ad911cbf04b34710637f0258"
"c21ebdcc0777aa7e14a8c201cde84660536f2fda172d4d9d0e5db55095aeab6e43e3b000"
"12b405824a2b14630d1f0612aae19de7badae3fc7c6c73ae56f8abf7519331ef8fe4b601"
"2ceb7be4d8b3ea70378905a9515772989ea846dbeb7a382b2fc027b7c2e19a17dff5d69c"
"d58cb86642d5041e7c364c1e3e45514d417222533df4577c6c33342445df84874aa6cb7c"
"03a3aa8e2d8201278774821abc0f7669abe04e70be37fcc82c91174fd5263b7b90b52d64"
"baf7d28ab48f389d8ebae75c52f10ab8c01bb6b1707e475994590203010001a382011030"
"82010c30120603551d130101ff040830060101ff020100300e0603551d0f0101ff040403"
"020204301d0603551d0e041604144bcbdfaa02de8dc3e7e585db2e8abe756b8a67583081"
"b20603551d230481aa3081a78014049466aaf96189b6dbb5f713383d6284b8180a8fa181"
"83a48180307e310b30090603550406130255533113301106035504080c0a57617368696e"
"67746f6e3111300f06035504070c084b69726b6c616e64310f300d060355040a0c06476f"
"6f676c653111300f060355040b0c085769646576696e653123302106035504030c1a7769"
"646576696e652e636f6d2f6f656d2d726f6f742d70726f64820900df86053101be9a9a30"
"12060a2b06010401d679040101040402021ee9300d06092a864886f70d01010b05000382"
"020100613f2f43e4be6634ef9206e988ba6a1d4f545a97b175d793f845c6839236fd55a9"
"210bdcf6ae11dc622144bd041d582c03f8e4e21ebae6dd19dd56fdce06735f941eb603db"
"3d7babab72647bde7d4dcf7ef09129c17713c26f80ab7aa8ceb01c2ac59cfb0be59f9c1b"
"c94b58df9618f7676789a4e91448acfa9d862aeb752c2bbf637dc74e7ead392db47c07a5"
"5ae83ad4f50c4ff3a29c3c32ed9d4b4905bc1fa013e6dd827906313bc697ec8daa4fef14"
"3c21f672b20942c774feef70bde98541300bb36b590c0f1175d4bbb1dfb1dfb3fab33a43"
"177d8a82aea207f88351fb16fb64b646dabe322bc0ee782a84a9540af92d6165dea59766"
"7902f89717e2d49f9eacccae999a0304bb45feb2f580babfdd24e5e61e5d36a5870cdf60"
"816fb75fb91fca753c1a63b0ebe695860daea6c92a94f1d0be75c8f807d788ffecf9cd49"
"c6fe4d7f441ed8afa9722798e25a08ea55d3b3eadc7669511001467d33949c94effe761c"
"c6d715533e8d3d299a586af1759eea1b4cf04776acc6a2324440dffeff9df4e2c2faa15f"
"2e66e997cb27266e53e4e8862cead3696c614ffec1c98b05926f4796cef033fa7c78249b"
"d78d36563786bc725af9b9b093f0817810f2b0c279915ecfbc8cf2320ff72d30d813774f"
"789e408de63a98b2aa134d2549346c809e1903dbcdf5b154741b673c46ac3e5da2d91383"
"30eb823b06ab3c397dd0683100");
// This is a private RSA key that is paired with the DRM certificate below.
const std::string kPrivateKeySampleDRMCert = a2bs_hex(
"308204BC020100300D06092A864886F70D0101010500048204A6308204A202010002820101"
"00E68EAD7C67ED983A72C89BC55054D26821C3399702E7906B77C7E09AE607D40B0013484B"
"0C557A810E19A814B4F14D55E60456EE21BC19F29EFFDA416BC9CBF0CE2C684E5A44F77008"
"038E0666EE7995166381E00F7EB2C38845F5CD2B790D35570D07D7EE225ED94A5D9421EE60"
"BCD075ADFBA71F4E7363DB5E0B1E05352F6945A3A1F0E41899A3BF1DE322FEECCCD577225B"
"CB79550D0014343EA64312EB32919B6E8D6EC1E349FA54074D829E80C8CE7E1E713AB50917"
"A4AC98C898A85F7C267417D35180CF1BF3E6CABE04C8AC6422F36137FAD800A83EABB8C970"
"C4248435F1B4C9C659865864BC714AF4D9A425F28626BEF9DB3A42510135FF2B69213F0203"
"010001028201000C5D9CAA6E7C8CCC9DB96AB9637C9928629F30E88B8C55EF9DA607C2E711"
"866AEC9F1C22824FD75932A367A36CAD0083D9E963AC33FCFDBB4891DA67E5DB15E81D76BE"
"456D8C03656BD89CF674F0D76E8A9BDDAC61C85ED823E7F4AE0365E3B277AFC83AE997C854"
"892B89B5642EA611DC2DEFB05FFA7A2FE1E5225D82D3FE6DE1F1B3DE0A5386E1F75FE21E20"
"E38A517FDFF1598BF9C2210EDDED222D9C6045494015E7FDC76084E57D2A58184E8F84153D"
"BD1CC5E0C2FB84085EEAA42A046205AA1B0BDC30DCF077941AC001C03BEE1E6F3F8E0D6A95"
"1C9672B54C11F3BBAB5F9F18816F32A7E3A1F1755CDEA30C2805D21C90891B6B1CC9601B0B"
"DE8601A902818100F41622BA193DF0D70D76FB47D38BFA711D52530DDC438B7F4A88685B60"
"B5D4A1937E8B63EC6FF4EA650BF129A7649A2A5376622AE2D5B4AD2064FC9E0A05C28D0510"
"412DDF5660BB008C4340965B80CC0A9CCA559B783179B6ECA6952999A86B8CECCE1582C3E0"
"E603E357D2FF59181EA3E3A25361C4E287DEB192132A4C2E2D02818100F1CF7ECBB795E456"
"D5C976E512EE63C25C79A3FAE9CF4B8C838950B69E97373819E838266678CD11DF45E9E9B0"
"A53183D79C6E1713A9F47A51E39DFC730EA76B3B0460E1A8E1BC932A84875610F79267C81F"
"F794E1FC80A8687AFE3120CC6A3EBAC1735FDFF20FE7809879F205F7C933845FC6B8D18DD7"
"88031B3E8B19155C9B028180510FCCE6AB1D640FB79C0D25B47EE7648B8D5CA1DCC5DDDD1F"
"5E9FF1C0F382334AED9AD34BA17EE01D40D30DB756F4D01BB9D42E53F90F30F3F235E73282"
"E932B63CC8B8B8545279A85BECB5D5797C13C76E7CCFE37B0E4B52D1D31CF49CE04F1F9541"
"77E95EAE2115A779F24BF545CA5F39691E71F8D616B3819B769BF482DD028180491A86E5C5"
"B1BE1F76707ACE5443D7CAF9B4189C11B586CC8B33A7401E7FEEC4BA2857595C9F66B7E17D"
"3C7356E10A3026ADF72668DE77B7C72BFE26450E8814C5F9D3E444EF41D868013AFD0D121B"
"A3DE7FB394C221593010AE264CE9F282A8464397C2C36C65DC822716AED19910ADCF763918"
"C4D991F05FA80BE77784DAC30281800C5FDD98BB2EF766B9D43784CC2FC22FC27D6F41BDCA"
"9A4EFB0197FFD599C3528B31E42B12BBA3788019C9B546F66B22C8AE91BAB5B4D86FF46C2F"
"6AF3D579C834A301AE61E0C01CA914D8C4DAA3AE0DA92ABEC1122A78055E8B257D0658E080"
"BC7C1184BDDA1133EB9951A1E80F2A4F2DC01A01A6035337DADE95E7B77394CB");
// This is a DRM certificate that was intercepted from a provisioning response
// from the production server to a device with the test keybox.
const std::string kPublicSampleDRMCert = a2bs_hex(
"0ABC02080212107CB49F987A635E1E0A52184694582D6E18A2C99EEC05228E023082010A02"
"82010100E68EAD7C67ED983A72C89BC55054D26821C3399702E7906B77C7E09AE607D40B00"
"13484B0C557A810E19A814B4F14D55E60456EE21BC19F29EFFDA416BC9CBF0CE2C684E5A44"
"F77008038E0666EE7995166381E00F7EB2C38845F5CD2B790D35570D07D7EE225ED94A5D94"
"21EE60BCD075ADFBA71F4E7363DB5E0B1E05352F6945A3A1F0E41899A3BF1DE322FEECCCD5"
"77225BCB79550D0014343EA64312EB32919B6E8D6EC1E349FA54074D829E80C8CE7E1E713A"
"B50917A4AC98C898A85F7C267417D35180CF1BF3E6CABE04C8AC6422F36137FAD800A83EAB"
"B8C970C4248435F1B4C9C659865864BC714AF4D9A425F28626BEF9DB3A42510135FF2B6921"
"3F020301000128E83D3A0C7769646576696E652E636F6D1280028F1B043BBFFF8B126F970C"
"9F0722C19DCDDD9A02146A8527249DC7CB78FEC38AF92935B37003B3B47D492A94E8787D40"
"86C6E754D4EB77A8C92F721A6516D7F91A308E8CE2EC4712C4FAA3ADB3482A63D816B10902"
"245D96B38D61F5D0053FC0302B338763F9CB1F3E843BDDE2B520770872F844E8C6BD8C611A"
"FA81EA5542BF0312335FC13ACC0679747BBC2F44459CDAA7241B119BE0158A0A90A2567C8B"
"096D733727E22B0CA24E248A94649F1F4D80CF588115E6675DF01C0192A4D0C5E6FCE326E4"
"2368DE6BF572D97D1AF140AC7DECDF8DC41A0276437D52AFDA2F7A6E76DA2B4466EBC63AA9"
"EA827DAC355B815D306A431CEEDF1D9C62E478E33B4CC41AB4050AAE020801121065802C9B"
"625E5A319C33DC1CB7C3C6D418E3A5BDD005228E023082010A0282010100B80502043C2A8A"
"0FD8D25C613E1E3E3B5E349F332F04516A7510D38021A5629B9AA027AEAD3C759B7AFE70BE"
"D65F3DF6860FF5EB60B983A3FFA33FDE06F3B73014DFC845AB371C6600562E9D904F842B8B"
"A4A5D9200FFA3ED45D705520A5C372A889F9E314386234C6897AE655851FCD9ADB4EF9126C"
"78386EA93BCB25BA3EC475C55C608E771C763AB02506F9B07252D6ABF7EA64B1EBDE7B95C6"
"407690533BD6890B9274C16066F74FC401EA355F0A02106814D49BF0C89E6E1F8DB2A47841"
"CD0DAD793296A107C36223404F2BF1FCA16FD0A4B982634DB62407F8F14ACAE3B05A038BD3"
"E4BBBAE4391BBFA7A47FB9D01DE857EA88E5E36EE36E245859FC0F020301000128E83D1280"
"037E06581A019184AB572AFDCADDD03F161CE68200F8E6F8AD161947360BC8D49C0D68009B"
"1C4644F9B3F3FB6DDFD92EF92DE62D41D459D29D81BFAEF3970A3A39D25B2662ECB03B2DA7"
"B68302FAA6DD98D95A143CC8C1CB6ADDA76D2EE9C3723FAF95A29CDC3E968B6821A91C051C"
"A280A86669710A1AD7A44BF9218027460DF694E2E9270396DF221963F21EE6AA220A5EE4A4"
"D0FEB3D53EB5732F8F91E9A96B3B8BE284C51339EA284D4D0EDD55B6AD56F7416420E05E05"
"9F9734A96BE25AA44560DBA8C38755A42A82BD7F88EDD19DF346A667B33B8114C76A8838C4"
"23D824A50B23251A088136D6E8F475299D2AFD46CEA51B5CBDF789A572125CD24FBB813B38"
"7A10CD2A30E3447634AB3408F96B9CF3D98896D405F3F540D9C57962760FCD177CDD101EB8"
"A4148B9C29CED5EAD645A95B698F1CDC6E1DB6678B85074186080D68D13CD37E07B16DE370"
"CD9AFB9B25564A73A30E2AF8085EA37D310C474F0E67AC00CA992A5296FAEDAD7AA06ECD79"
"0F1E3D426558FA98383E3CD2ED4830");
} // namespace
FakeProvisioningServer::FakeProvisioningServer() {
// Generate a service certificate that can convince the CDM we are a real
// provisioning server. it only works if the CDM is compiled with the symbol
// ACCEPT_TEST_CERT defined.
video_widevine::DrmDeviceCertificate cert;
cert.set_type(video_widevine::DrmDeviceCertificate_CertificateType_SERVICE);
cert.set_public_key(kPublicFakeServiceCert);
cert.set_serial_number("Serial Number 007");
cert.set_provider_id("Unit Test Provider");
std::string serialized_cert;
cert.SerializeToString(&serialized_cert);
video_widevine::SignedDrmDeviceCertificate signed_cert;
signed_cert.set_drm_certificate(serialized_cert);
signed_cert.SerializeToString(&service_certificate_);
}
bool FakeProvisioningServer::MakeResponse(
const std::string& serialized_signed_request, std::string* json_response) {
if (json_response == nullptr) {
LOGE("json_response is jullptr.");
return false;
}
json_response->clear();
// First, parse the signed request and the request.
video_widevine::SignedProvisioningMessage signed_request;
if (!signed_request.ParseFromString(serialized_signed_request)) {
LOGE("Failed to parse signed provisioning request");
return false;
}
std::string serialized_message = signed_request.message();
video_widevine::ProvisioningRequest provisioning_request;
if (!provisioning_request.ParseFromString(serialized_message)) {
LOGE("Failed to parse provisioning request");
return false;
}
std::string request_signature = signed_request.signature();
LOGD("Requested certificate type %s",
provisioning_request.options().certificate_type() ==
video_widevine::ProvisioningOptions::WIDEVINE_DRM
? "WIDEVINE_DRM"
: "X509");
video_widevine::SignedProvisioningMessage::ProtocolVersion version =
signed_request.protocol_version();
LOGD("Request uses protocol version: %d", version);
if (version != video_widevine::SignedProvisioningMessage::PROVISIONING_20) {
LOGE("Fake provisioning server only handles Keyboxes");
return false;
}
// Next, we derive the keys from the keybox device key. This is Provisioning
// 2.0 specific.
// TODO(b/141438127): Add support for provisioing 3.0.
std::string mac_context;
GenerateMacContext(serialized_message, &mac_context);
std::vector<uint8_t> mac_context_v(mac_context.begin(), mac_context.end());
std::string enc_context;
GenerateEncryptContext(serialized_message, &enc_context);
std::vector<uint8_t> enc_context_v(enc_context.begin(), enc_context.end());
wvoec::KeyDeriver key_deriver;
// Not only is this Prov 2.0 specific, it assumes the device is using the
// standard test keybox.
key_deriver.DeriveKeys(wvoec::kTestKeybox.device_key_, mac_context_v,
enc_context_v);
// Create a structure to hold the RSA private key. This is used by the key
// deriver to encrypt the key.
wvoec::RSAPrivateKeyMessage clear_rsa_key;
if (sizeof(clear_rsa_key.rsa_key) < kPrivateKeySampleDRMCert.size()) {
LOGE("Private key too big");
return false;
}
memcpy(clear_rsa_key.rsa_key, kPrivateKeySampleDRMCert.data(),
kPrivateKeySampleDRMCert.size());
clear_rsa_key.rsa_key_length = kPrivateKeySampleDRMCert.size();
wvoec::RSAPrivateKeyMessage encrypted_rsa_key;
key_deriver.PadAndEncryptProvisioningMessage(&clear_rsa_key,
&encrypted_rsa_key);
// Fill out the provisioning response with the public DRM cert, and the
// encrypted private RSA key.
video_widevine::ProvisioningResponse provisioning_response;
provisioning_response.set_device_certificate(kPublicSampleDRMCert);
provisioning_response.set_device_rsa_key(std::string(
encrypted_rsa_key.rsa_key,
encrypted_rsa_key.rsa_key + encrypted_rsa_key.rsa_key_length));
provisioning_response.set_device_rsa_key_iv(std::string(
encrypted_rsa_key.rsa_key_iv,
encrypted_rsa_key.rsa_key_iv + sizeof(encrypted_rsa_key.rsa_key_iv)));
provisioning_response.set_nonce(provisioning_request.nonce());
// Sign the response.
video_widevine::SignedProvisioningMessage signed_response;
signed_response.set_protocol_version(signed_request.protocol_version());
std::string message;
provisioning_response.SerializeToString(&message);
signed_response.set_message(message);
if (signed_request.has_oemcrypto_core_message()) {
// If the request has a core message, then the response should also have a
// core message.
std::string core_request = signed_request.oemcrypto_core_message();
oemcrypto_core_message::ODK_ProvisioningRequest core_request_data;
if (!oemcrypto_core_message::deserialize::
CoreProvisioningRequestFromMessage(core_request,
&core_request_data)) {
LOGE("Core request did not parse.");
return false;
}
std::string core_response;
oemcrypto_core_message::serialize::CreateCoreProvisioningResponseFromProto(
message, core_request_data, &core_response);
signed_response.set_oemcrypto_core_message(core_response);
// Also, the signature should be over the concatenation of the core message
// and the message body. This is done to ensure that neither the message
// body, nor the oemcrypto core message are tampered with. See "Widevine
// Core Message Serialization" for details.
message = core_response + message;
}
std::vector<uint8_t> signature_v;
key_deriver.ServerSignBuffer(reinterpret_cast<const uint8_t*>(message.data()),
message.size(), &signature_v);
std::string signature(signature_v.begin(), signature_v.end());
signed_response.set_signature(signature);
// Finally, base 64 encode and surround with just enough fake json to fool the
// CDM.
std::string response_data;
signed_response.SerializeToString(&response_data);
std::vector<uint8_t> response_data_v(response_data.begin(),
response_data.end());
static const std::string json_start = "{ \"signedResponse\": \"";
static const std::string json_end = "\" }";
*json_response = json_start + Base64SafeEncode(response_data_v) + json_end;
return true;
}
} // namespace wvcdm