diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-06 23:31:16 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-06 23:31:16 +0100 |
| commit | 4313456938d34d93239194e914b82e7a5ae14c1c (patch) | |
| tree | 622dffc47d90a14b70eecd35b0e5717a9b80fade | |
| parent | 3340b9a66ca2153daf8568ae147abcc9c5983323 (diff) | |
Can decrypt a KDM.
| -rw-r--r-- | src/kdm.cc | 154 | ||||
| -rw-r--r-- | src/kdm.h | 92 | ||||
| -rw-r--r-- | src/wscript | 5 | ||||
| -rw-r--r-- | test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml | 192 | ||||
| -rw-r--r-- | test/data/private.key | 27 | ||||
| -rw-r--r-- | test/kdm_test.cc | 44 | ||||
| -rw-r--r-- | test/tests.cc | 1 |
7 files changed, 513 insertions, 2 deletions
diff --git a/src/kdm.cc b/src/kdm.cc new file mode 100644 index 00000000..14a351e1 --- /dev/null +++ b/src/kdm.cc @@ -0,0 +1,154 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <iomanip> +#include <openssl/rsa.h> +#include <openssl/pem.h> +#include <libcxml/cxml.h> +#include "KM_util.h" +#include "kdm.h" +#include "exceptions.h" + +using std::list; +using std::string; +using std::stringstream; +using std::hex; +using std::setw; +using std::setfill; +using boost::shared_ptr; +using namespace libdcp; + +KDM::KDM (boost::filesystem::path kdm, boost::filesystem::path private_key) +{ + /* Read the private key */ + + FILE* private_key_file = fopen (private_key.string().c_str(), "r"); + if (!private_key_file) { + throw FileError ("could not find RSA private key file", private_key.string ()); + } + + RSA* rsa = PEM_read_RSAPrivateKey (private_key_file, 0, 0, 0); + fclose (private_key_file); + if (!rsa) { + throw FileError ("could not read RSA private key file", private_key.string ()); + } + + + /* Read the KDM, decrypting it */ + + cxml::File f (kdm.string (), "DCinemaSecurityMessage"); + + shared_ptr<cxml::Node> authenticated_private = f.node_child ("AuthenticatedPrivate"); + list<shared_ptr<cxml::Node> > encrypted_keys = authenticated_private->node_children ("EncryptedKey"); + + for (list<shared_ptr<cxml::Node> >::iterator i = encrypted_keys.begin(); i != encrypted_keys.end(); ++i) { + + /* Get the base-64-encoded cipher value from the KDM */ + shared_ptr<cxml::Node> cipher_data = (*i)->node_child ("CipherData"); + shared_ptr<cxml::Node> cipher_value_base64 = cipher_data->node_child ("CipherValue"); + + /* Decode it from base-64 */ + unsigned char cipher_value[256]; + ui32_t cipher_value_len; + if (Kumu::base64decode (cipher_value_base64->content().c_str(), cipher_value, sizeof (cipher_value), &cipher_value_len)) { + RSA_free (rsa); + throw MiscError ("could not base-64-decode CipherValue from KDM"); + } + + /* Decrypt it */ + unsigned char decrypted[256]; + unsigned int const decrypted_len = RSA_private_decrypt (cipher_value_len, cipher_value, decrypted, rsa, RSA_PKCS1_OAEP_PADDING); + assert (decrypted_len < sizeof (decrypted)); + + _ciphers.push_back (KDMCipher (decrypted, decrypted_len)); + } + + RSA_free (rsa); +} + + +KDMCipher::KDMCipher (unsigned char const * raw, int len) +{ + switch (len) { + case 134: + /* interop */ + _structure_id = get (&raw, 16); + _signer_thumbprint = get (&raw, 20); + _cpl_id = get_uuid (&raw, 16); + _key_id = get_uuid (&raw, 16); + _not_valid_before = get (&raw, 25); + _not_valid_after = get (&raw, 25); + _key_data = get_hex (&raw, 16); + break; + case 138: + /* SMPTE */ + _structure_id = get (&raw, 16); + _signer_thumbprint = get (&raw, 20); + _cpl_id = get_uuid (&raw, 16); + _key_type = get (&raw, 4); + _key_id = get_uuid (&raw, 16); + _not_valid_before = get (&raw, 25); + _not_valid_after = get (&raw, 25); + _key_data = get_hex (&raw, 16); + break; + default: + assert (false); + } +} + +string +KDMCipher::get (unsigned char const ** p, int N) const +{ + string g; + for (int i = 0; i < N; ++i) { + g += **p; + (*p)++; + } + + return g; +} + +string +KDMCipher::get_uuid (unsigned char const ** p, int N) const +{ + stringstream g; + + for (int i = 0; i < N; ++i) { + g << setw(2) << setfill('0') << hex << static_cast<int> (**p); + (*p)++; + if (i == 3 || i == 5 || i == 7 || i == 9) { + g << '-'; + } + } + + return g.str (); +} + +string +KDMCipher::get_hex (unsigned char const ** p, int N) const +{ + stringstream g; + + for (int i = 0; i < N; ++i) { + g << setw(2) << setfill('0') << hex << static_cast<int> (**p); + (*p)++; + } + + return g.str (); +} diff --git a/src/kdm.h b/src/kdm.h new file mode 100644 index 00000000..0b450987 --- /dev/null +++ b/src/kdm.h @@ -0,0 +1,92 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <boost/filesystem.hpp> + +namespace libdcp { + +class KDMCipher +{ +public: + KDMCipher (unsigned char const *, int); + + std::string structure_id () const { + return _structure_id; + } + + std::string signer_thumbprint () const { + return _signer_thumbprint; + } + + std::string cpl_id () const { + return _cpl_id; + } + + std::string key_type () const { + return _key_type; + } + + std::string key_id () const { + return _key_id; + } + + std::string not_valid_before () const { + return _not_valid_before; + } + + std::string not_valid_after () const { + return _not_valid_after; + } + + std::string key_data () const { + return _key_data; + } + +private: + std::string get (unsigned char const **, int) const; + std::string get_uuid (unsigned char const **, int) const; + std::string get_hex (unsigned char const **, int) const; + + std::string _structure_id; + std::string _signer_thumbprint; + std::string _cpl_id; + std::string _key_type; + std::string _key_id; + std::string _not_valid_before; + std::string _not_valid_after; + std::string _key_data; +}; + +class KDM +{ +public: + KDM (boost::filesystem::path, boost::filesystem::path); + + std::list<KDMCipher> ciphers () const { + return _ciphers; + } + +private: + std::list<KDMCipher> _ciphers; +}; + + +} + + diff --git a/src/wscript b/src/wscript index 93d6d5c1..acbfdfc0 100644 --- a/src/wscript +++ b/src/wscript @@ -10,19 +10,20 @@ def build(bld): obj.uselib = 'BOOST_FILESYSTEM BOOST_SIGNALS2 BOOST_DATETIME OPENSSL SIGC++ LIBXML++ OPENJPEG CXML XMLSEC1' obj.use = 'libkumu-libdcp libasdcp-libdcp' obj.source = """ + argb_frame.cc asset.cc - dcp.cc certificates.cc crypt_chain.cc cpl.cc + dcp.cc dcp_time.cc gamma_lut.cc + kdm.cc metadata.cc mxf_asset.cc picture_asset.cc picture_frame.cc reel.cc - argb_frame.cc sound_asset.cc sound_frame.cc subtitle_asset.cc diff --git a/test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml b/test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml new file mode 100644 index 00000000..79949013 --- /dev/null +++ b/test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="UTF-8"?> +<DCinemaSecurityMessage xmlns="http://www.smpte-ra.org/schemas/430-3/2006/ETM" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:enc="http://www.w3.org/2001/04/xmlenc#"> + <!-- cinemaslides v0.2013.04.27 smpte kdm t1 --> + <AuthenticatedPublic Id="ID_AuthenticatedPublic"> + <MessageId>urn:uuid:8971c838-d0c3-405d-bc57-43afa9d91242</MessageId> + <MessageType>http://www.smpte-ra.org/430-1/2006/KDM#kdm-key-type</MessageType> + <AnnotationText>cinemaslides 2013-07-06T21:10:29+01:00</AnnotationText> + <IssueDate>2013-07-06T21:10:29+01:00</IssueDate> + <Signer> + <ds:X509IssuerName>dnQualifier=5\+kdb\+9R\+/FhxzwAJ71I2V2cxEM=,CN=.smpte-430-2.INTERMEDIATE.NOT_FOR_PRODUCTION,OU=example.org,O=example.org</ds:X509IssuerName> + <ds:X509SerialNumber>7</ds:X509SerialNumber> + </Signer> + <RequiredExtensions> + <KDMRequiredExtensions xmlns="http://www.smpte-ra.org/schemas/430-1/2006/KDM"> + <Recipient> + <X509IssuerSerial> + <ds:X509IssuerName>dnQualifier=L7hRU1k0AaJM23TJg2PYWmflEVk=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org</ds:X509IssuerName> + <ds:X509SerialNumber>5</ds:X509SerialNumber> + </X509IssuerSerial> + <X509SubjectName>dnQualifier=L7hRU1k0AaJM23TJg2PYWmflEVk=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org</X509SubjectName> + </Recipient> + <CompositionPlaylistId>urn:uuid:eece17de-77e8-4a55-9347-b6bab5724b9f</CompositionPlaylistId> + <ContentTitleText>TONEPLATES-SMPTE-ENCRYPTED_TST_F_XX-XX_ITL-TD_51-XX_2K_WOE_20111001_WOE_OV</ContentTitleText> + <ContentKeysNotValidBefore>2013-07-06T20:04:58+00:00</ContentKeysNotValidBefore> + <ContentKeysNotValidAfter>2023-07-02T20:04:56+00:00</ContentKeysNotValidAfter> + <AuthorizedDeviceInfo> + <DeviceListIdentifier>urn:uuid:014d91e5-616d-4c21-8cfa-48da04b5b9d8</DeviceListIdentifier> + <DeviceListDescription>.smpte-430-2.ROOT.NOT_FOR_PRODUCTION</DeviceListDescription> + <DeviceList> + <CertificateThumbprint>/Pk3/NK4Quql1hKTLnASAi5xzL0=</CertificateThumbprint> + </DeviceList> + </AuthorizedDeviceInfo> + <KeyIdList> + <TypedKeyId> + <KeyType>MDIK</KeyType> + <KeyId>urn:uuid:4ac4f922-8239-4831-b23b-31426d0542c4</KeyId> + </TypedKeyId> + <TypedKeyId> + <KeyType>MDAK</KeyType> + <KeyId>urn:uuid:73baf5de-e195-4542-ab28-8a465f7d4079</KeyId> + </TypedKeyId> + </KeyIdList> + <ForensicMarkFlagList> + <ForensicMarkFlag>http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-picture-disable</ForensicMarkFlag> + <ForensicMarkFlag>http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-audio-disable</ForensicMarkFlag> + </ForensicMarkFlagList> + </KDMRequiredExtensions> + </RequiredExtensions> + <NonCriticalExtensions/> + </AuthenticatedPublic> + <AuthenticatedPrivate Id="ID_AuthenticatedPrivate"> + <enc:EncryptedKey> + <enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"> + <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> + </enc:EncryptionMethod> + <enc:CipherData> + <enc:CipherValue>BGMEgy18q3BwOD6jMrgxlwjI/FKUVTgcRe1gpTUxg52HZr9Iu3iQo+AhO6hg4ti1 +1maakj3gi6b++8qKbm5HkqA8hzjsh54NWf/cOGnHHsM/o+1fxLqPI5u37EHymxv0 +uC18F2Ad9g1wUf0BITDrtdjC19yTGoPYD+VHuUZvZrIHs5Otw4Buhg1+N3VDc0vz +/n+udK9MkktRY+Z0LPyDARcXksjFPkTKkZBOw815StG7GXlGcg0ndMVVN7+9l4Xf +97EWRTv3wEoMI140NA5vvcPWm8DjbaZgShlmOf9ZqM6N24eTRKut+62ljsupMGFB +ffYMzb6hsGwaYKVzPw2W3A==</enc:CipherValue> + </enc:CipherData> + </enc:EncryptedKey> + <enc:EncryptedKey> + <enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"> + <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> + </enc:EncryptionMethod> + <enc:CipherData> + <enc:CipherValue>PAWbXs8QI1+opF9jrcuwqcM1QIl6/pB4zlzvBMpmidiwgqozox1DIMgTt5K9wqV5 +hYiLfEgyiXrJcO9IbUa1g7YeySP6In/FGu/JcdYe/dAe0II7F8xJhIxZHRT0l5PE +ZmiLFZO3Ax5aluKX2PzIztrxdrIlGI3jAMLVACYiNQGAlwUCobhOFwmyXX/x+0iN +ULJ459WCsY45AMkSAWzoztR8xY8DNa9K6zTOotxFemv+wjwFqSdzyHhaZOWvYHan +0JtPuELBZnuMcqvMUsQ5TETYak2Pj2QCVWX2Ahcek73oyRWWK7gwKf5DRTMoOwtP +gKhBADcETNFQligfz33wMA==</enc:CipherValue> + </enc:CipherData> + </enc:EncryptedKey> + </AuthenticatedPrivate> + <ds:Signature> + <ds:SignedInfo> + <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/> + <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> + <ds:Reference URI="#ID_AuthenticatedPublic"> + <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> + <ds:DigestValue>u/EsQFMekv8vXKn6glbc1vvNZptz18/UKkVBtdrgFOU=</ds:DigestValue> + </ds:Reference> + <ds:Reference URI="#ID_AuthenticatedPrivate"> + <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> + <ds:DigestValue>OaEm1HINvc6t9a/Z6ut1+C3JV+sOPDeRGv13TWVXsO8=</ds:DigestValue> + </ds:Reference> + </ds:SignedInfo> + <ds:SignatureValue>TMeBgzdDJxn4aNCJnaaXd91m4B91qmstqluYEC9e0TkX6YWeEmqeOCwcjy7aXk4P +f66zGtvNsEFA9b0d6zpqX7XnlR7cgYS++jeIjgqzIHAoMQSu4GdjFo4WAutoHkab +a6+LwzWbU2nPCcvZT0BSLxbfrczNEGwzlfY5IU0cUtCrI5KcdobI0jecgEhiZksR +OzBP2CxWC2NfOZYsemSOxCzazjRpl7zY5c0Bm2yEzjVmoY2IQQIaoK7+MKyHxDxe +JroVBnynlFLznjutTfQ7VIWiCUOkNuRstxlLb6xA7mijzMI8JaTjoLfHF7Hv/BDx +cZg3PhW/dxLWw1v3u3RQmQ==</ds:SignatureValue> + <ds:KeyInfo> + <ds:X509Data> + <ds:X509IssuerSerial> + <ds:X509IssuerName>dnQualifier=5\+kdb\+9R\+/FhxzwAJ71I2V2cxEM=,CN=.smpte-430-2.INTERMEDIATE.NOT_FOR_PRODUCTION,OU=example.org,O=example.org</ds:X509IssuerName> + <ds:X509SerialNumber>7</ds:X509SerialNumber> + </ds:X509IssuerSerial> + <ds:X509Certificate>MIIEezCCA2OgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBijEUMBIGA1UEChMLZXhh +bXBsZS5vcmcxFDASBgNVBAsTC2V4YW1wbGUub3JnMTUwMwYDVQQDFCwuc21wdGUt +NDMwLTIuSU5URVJNRURJQVRFLk5PVF9GT1JfUFJPRFVDVElPTjElMCMGA1UELhMc +NStrZGIrOVIrL0ZoeHp3QUo3MUkyVjJjeEVNPTAeFw0xMzA3MDYyMDA0NTdaFw0y +MzA3MDIyMDA0NTdaMIGEMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEUMBIGA1UECxML +ZXhhbXBsZS5vcmcxLzAtBgNVBAMUJkNTLnNtcHRlLTQzMC0yLkxFQUYuTk9UX0ZP +Ul9QUk9EVUNUSU9OMSUwIwYDVQQuExxWMWJVOWRoZlBEZFdZNldydzlXQjdJYWR4 +QWc9MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA22bL2XgFrlegWg1Y +wA62mL4VOTAz7jY6s01JfdwxKIsYW+A7Tgg2LmasTKsCGiJnXcRHRN21s0I3dLV7 +kxtig9STnSFiIPdMbMk9f06xFvntshc8cYgEfPldA+hfkaiBkOxQ235kUpo/uN1o +vL1xWr5PfdjJNz2/WcfEWeQddHy5mc4SFv/TvQsiaPuwr6iI/1vUEMIRkmiu6G7r +Fs9kuL+KljF71eorwZagv+OFOd1+M7ejT+jlcWdqCMBBomcHvzduUgP8VpKHc89E +hDxDQsFLqmmWaNenra4XHOFVrYcs+aGKjPCSaFTggTNOOMFI6qVXW/ZsE03zmgS/ +aNEq1wIDAQABo4HvMIHsMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgWgMB0GA1Ud +DgQWBBRXVtT12F88N1ZjpavD1YHshp3ECDCBrwYDVR0jBIGnMIGkgBTn6R1v71H7 +8WHHPAAnvUjZXZzEQ6GBiKSBhTCBgjEUMBIGA1UEChMLZXhhbXBsZS5vcmcxFDAS +BgNVBAsTC2V4YW1wbGUub3JnMS0wKwYDVQQDFCQuc21wdGUtNDMwLTIuUk9PVC5O +T1RfRk9SX1BST0RVQ1RJT04xJTAjBgNVBC4THEw3aFJVMWswQWFKTTIzVEpnMlBZ +V21mbEVWaz2CAQYwDQYJKoZIhvcNAQELBQADggEBAHV2HYFW4PEWOYZq+Y6KnFcD +bod8NCsCmTmO+L7zXi3yY4rtqqP3aKbr4nGINaC8+XqY6fYsgaNvPRInn+Nkh7xH +FQbi8RUuFQ4R75O8VhXk3JYhwDoES/FPOqwtHN3MiOO15dbWwLkwqa/K2bkkZbpG +5mFmuHHy8GomvZJkZQ6TNvlMQWj4+FgrBM0EFuJwm8LS+Ek7f98Gi4yxlBumMt4X +N/s/8ejaChGueEGX9Akiu5KFBZrpEzneveLXHndaL56slmyTe38R07EbXwHK35Rk +giGcueg9LxGmWfB7hS4ONx2R4oWYN4Naf9QRD3u37dpv8w3mHj2SihUPmCMxL1E=</ds:X509Certificate> + </ds:X509Data> + <ds:X509Data> + <ds:X509IssuerSerial> + <ds:X509IssuerName>dnQualifier=L7hRU1k0AaJM23TJg2PYWmflEVk=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org</ds:X509IssuerName> + <ds:X509SerialNumber>6</ds:X509SerialNumber> + </ds:X509IssuerSerial> + <ds:X509Certificate>MIIEfzCCA2egAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBgjEUMBIGA1UEChMLZXhh +bXBsZS5vcmcxFDASBgNVBAsTC2V4YW1wbGUub3JnMS0wKwYDVQQDFCQuc21wdGUt +NDMwLTIuUk9PVC5OT1RfRk9SX1BST0RVQ1RJT04xJTAjBgNVBC4THEw3aFJVMWsw +QWFKTTIzVEpnMlBZV21mbEVWaz0wHhcNMTMwNzA2MjAwNDU2WhcNMjMwNzAzMjAw +NDU2WjCBijEUMBIGA1UEChMLZXhhbXBsZS5vcmcxFDASBgNVBAsTC2V4YW1wbGUu +b3JnMTUwMwYDVQQDFCwuc21wdGUtNDMwLTIuSU5URVJNRURJQVRFLk5PVF9GT1Jf +UFJPRFVDVElPTjElMCMGA1UELhMcNStrZGIrOVIrL0ZoeHp3QUo3MUkyVjJjeEVN +PTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPhsUkgBjWY4yTaegpvy +cW/S3gVcBZN+GO1qBxMZADAlp87YKVGw5TRfHjIppC0wClq3zS5rSv07diAOcZd7 +pXqusCokrTHBsKG3S8u0JEXn2AWnNgX7dD8gxE1ZV41Mm+reI4eE9fpntgzqrV6E +x8qlxkCAHrBPJNWVJHfpVifeKtjbb4/4K6GK9pZ/ejZ4tDBrYgS15S6s/7IZOyVb +d/XckanEcCeNEv7KgW8nwbm5ryI27++ogJECCBzadGHcb/lcx/xSVqAlMuBK884c +duz16+u+OC+1TLCb11B5VVWoVji5CGW1sOYVaMK+XZeyyIjk+fhF0P8DU9SOSa5f +cZMCAwEAAaOB9TCB8jASBgNVHRMBAf8ECDAGAQH/AgECMAsGA1UdDwQEAwIBBjAd +BgNVHQ4EFgQU5+kdb+9R+/FhxzwAJ71I2V2cxEMwga8GA1UdIwSBpzCBpIAUL7hR +U1k0AaJM23TJg2PYWmflEVmhgYikgYUwgYIxFDASBgNVBAoTC2V4YW1wbGUub3Jn +MRQwEgYDVQQLEwtleGFtcGxlLm9yZzEtMCsGA1UEAxQkLnNtcHRlLTQzMC0yLlJP +T1QuTk9UX0ZPUl9QUk9EVUNUSU9OMSUwIwYDVQQuExxMN2hSVTFrMEFhSk0yM1RK +ZzJQWVdtZmxFVms9ggEFMA0GCSqGSIb3DQEBCwUAA4IBAQAHH9Wi9740Eh+BnpXf +YztVm2x0Pzg9Xgr1O9iSNffQPf3C0GYA3WNFoWOnVfAUNpK8GU5vbFr8+CtdRPuW +02dJJ3q0C0pi/21mxuYvQVX8vNFGbFK7C4AT7NdKgeMpFvPfGDapITd4iR/oQWw3 +lix+gb/CK0km5IWxNJN2YkzM3YUf9SHBr05gJqtBciXa0ZhIMqR4qXNokzvKotuH +ZZZz9GsnHur4SmflEffbc5xZsMWFZWq5w0uSIvE4s9ZrugC1HKQWlS+1At8E0att +33S8pGKbOdhSK62c/wXapxAouVzx0M8izJ2GEGh7BPpzAP4k5d3LYxw8MHXlem0H +BGSw</ds:X509Certificate> + </ds:X509Data> + <ds:X509Data> + <ds:X509IssuerSerial> + <ds:X509IssuerName>dnQualifier=L7hRU1k0AaJM23TJg2PYWmflEVk=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org</ds:X509IssuerName> + <ds:X509SerialNumber>5</ds:X509SerialNumber> + </ds:X509IssuerSerial> + <ds:X509Certificate>MIIEdzCCA1+gAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBgjEUMBIGA1UEChMLZXhh +bXBsZS5vcmcxFDASBgNVBAsTC2V4YW1wbGUub3JnMS0wKwYDVQQDFCQuc21wdGUt +NDMwLTIuUk9PVC5OT1RfRk9SX1BST0RVQ1RJT04xJTAjBgNVBC4THEw3aFJVMWsw +QWFKTTIzVEpnMlBZV21mbEVWaz0wHhcNMTMwNzA2MjAwNDU2WhcNMjMwNzA0MjAw +NDU2WjCBgjEUMBIGA1UEChMLZXhhbXBsZS5vcmcxFDASBgNVBAsTC2V4YW1wbGUu +b3JnMS0wKwYDVQQDFCQuc21wdGUtNDMwLTIuUk9PVC5OT1RfRk9SX1BST0RVQ1RJ +T04xJTAjBgNVBC4THEw3aFJVMWswQWFKTTIzVEpnMlBZV21mbEVWaz0wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTQn+d3YhStTcHlzYToU6z7NE/YF+G +JJalU1BHa58aQ9272o4p/c0+2KJOvl5peIYASZYpuGQpv802H4cP6axCt44a6MJx +j9P63nq83TKdeus85Lr3ACk22646rlDh2PpxOxWrzvsvGE0PCI1Pa7kPFg9xtvi2 +zLE3wPIHtZ326VEv8BIwWXKPwEYp/HOUQvTZf2pWtZTXHQZ9T8k8Vtq32e3tyEsf +icC4p1arYAT1AWWVaJonTscLoz8HledVIx3yv+QN0AJ3wf5QcJRx5t2Tdc7O9ovl +Uzrl9fzhAfzPUtmIG1aCoZVZCQgaKy09+QFN6jZxWT89DuSBygZTEHKRAgMBAAGj +gfUwgfIwEgYDVR0TAQH/BAgwBgEB/wIBAzALBgNVHQ8EBAMCAQYwHQYDVR0OBBYE +FC+4UVNZNAGiTNt0yYNj2Fpn5RFZMIGvBgNVHSMEgacwgaSAFC+4UVNZNAGiTNt0 +yYNj2Fpn5RFZoYGIpIGFMIGCMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEUMBIGA1UE +CxMLZXhhbXBsZS5vcmcxLTArBgNVBAMUJC5zbXB0ZS00MzAtMi5ST09ULk5PVF9G +T1JfUFJPRFVDVElPTjElMCMGA1UELhMcTDdoUlUxazBBYUpNMjNUSmcyUFlXbWZs +RVZrPYIBBTANBgkqhkiG9w0BAQsFAAOCAQEAQYn1ySQE/cvAfy4g7m0w03mPKhbf +rNI56HrZJebrJGvBItWafzVTlTiHY6AgepGQ/qdfXIK4EttSRIeXTDxlLA9Mf+mw +kU9E6ZR4WBVGD+zLw5z/aFakNTyYDk0o/gxe3njNY6/KT+0fdmtnfnAVymqDE3z7 +Nm6UfDMVsrJ/wIZ7TKGmeo3IwAcPeF5+SminJ3OhpRDSeY+ZomwEtPvpi3N1tlHk +vYZE7iB+onjFT+FOjtLCeGtRbePfJuh8YrSGzc6dCeCeK0CwUr3bvnVfqzhiZYRn +6KGFx4EGJ//GOagj4VOKtftV0+SZeQtwBxhuzkBnx+wH48uuhNa7rwtslQ==</ds:X509Certificate> + </ds:X509Data> + </ds:KeyInfo> + </ds:Signature> +</DCinemaSecurityMessage> diff --git a/test/data/private.key b/test/data/private.key new file mode 100644 index 00000000..09991ac5 --- /dev/null +++ b/test/data/private.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA00J/nd2IUrU3B5c2E6FOs+zRP2BfhiSWpVNQR2ufGkPdu9qO +Kf3NPtiiTr5eaXiGAEmWKbhkKb/NNh+HD+msQreOGujCcY/T+t56vN0ynXrrPOS6 +9wApNtuuOq5Q4dj6cTsVq877LxhNDwiNT2u5DxYPcbb4tsyxN8DyB7Wd9ulRL/AS +MFlyj8BGKfxzlEL02X9qVrWU1x0GfU/JPFbat9nt7chLH4nAuKdWq2AE9QFllWia +J07HC6M/B5XnVSMd8r/kDdACd8H+UHCUcebdk3XOzvaL5VM65fX84QH8z1LZiBtW +gqGVWQkIGistPfkBTeo2cVk/PQ7kgcoGUxBykQIDAQABAoIBAQDEONfgAYxFhhv+ +6OxJf2JirGwOua0AI6vpE2FVdRjqhG7HtVCmoB6raPwYt6lpvZB5Y+AeEC64uHYa +912z4g8mSOetBtTUNgtm0I6gLbR9oVYt0SX3liax1YoW5yIpJCg6U+7lDfMw4xlw +BTl7s0rIQG1H6fNJlwZkCsrDbmWyl4PKcb6Kqfw4iafQmCRAJx9gvYW0QXigaxU5 +xSJRiA5Y4Ts0ZhH+RwKzNVap4IhWtKoIZS2Vvz+H1/iPavs9axdcyhfXg+9mOkT1 +4x3LQlNAmcYzUBByJN1d+yzoCVb3s8aP5vcWvR3t9TlnutBhKFGvJo0Jbfx1z5fx +b45+rjihAoGBAOv3thZeyqfLjl3tG00EhkDDxVvlDYtCfuyhNT7w/tCWlyoS1Wsh +iar0/yp/7wXMkasEaq0E/G2Srez39F9wd2GSuymmtMBzzXL8SXWIpfYlizgo/Zun +fRNNMDxYsY4Gaq4/QU7YCOzmAs1iZPyk10s8RYkUuS49ZGbgC1fy1bUDAoGBAOUx +z4/4R71mIlyr5/XGoWt7HDy7LD1AFlscBJ7bTFTzePuL8kawrm0P5Rg4zTTkJqZs +/ukVng+PRD+gY0cPEdwrZH6CTxMjxps1TPSGrM7KFK6//J+ez5iYordVhMEB2vRC +tIVN2tEcx9JdqCUb1k1esBlCZ1E1tyaFsAMzZTPbAoGBAJ+RbYMHKwf5MRb3JkUY +0CivuqB/7n7Dws0F3tnnYolvrF15SvUdQtlmv77fsKU9Ryxc2j6SZpk6XX8n1gtM +JI7JCOQLpaOXK9GcJZjjhUdE8DZUEdvWkVAiHIJSgA9I649VmzZUBQUeLbrx1NS8 +LBLmeSdP6kIIpgKjc0hQIJA9AoGAQAejaiA9wo73CJbKDeK5E/Ln15ue51mxJTD1 +pX+0moMOiI/3VoJjqHppUVQFGEKo/ZOzv2BXsRcgRPpE4gQ2xCCnSaST/M/g21mP +rzy0qGzSTGO8aseOTZ5OzxMoLFedWOIN1rQCbqsws/eQUxWs0B6k6dmgTZLJIQz2 +OF6yZkMCgYArWYrcsefBFznwckK3S+EXZeYApyREmWywHtuC6NKmWfksRtDce8B6 +Hs6T7xClvbd99h4CNf4nywRBRAO85HfSTkjamLB42xoGrWizeN3XGou6NA5im9IO +dRSNHaS084mEm9/HaxfvWHTLsUaArjDG/26ji236Dr6m3+ghDIUJMQ== +-----END RSA PRIVATE KEY----- diff --git a/test/kdm_test.cc b/test/kdm_test.cc new file mode 100644 index 00000000..172661e3 --- /dev/null +++ b/test/kdm_test.cc @@ -0,0 +1,44 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "kdm.h" + +BOOST_AUTO_TEST_CASE (kdm_test) +{ + libdcp::KDM kdm ( + "test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml", + "test/data/private.key" + ); + + list<libdcp::KDMCipher> ciphers = kdm.ciphers (); + + BOOST_CHECK_EQUAL (ciphers.size(), 2); + + BOOST_CHECK_EQUAL (ciphers.front().cpl_id(), "eece17de-77e8-4a55-9347-b6bab5724b9f"); + BOOST_CHECK_EQUAL (ciphers.front().key_id(), "4ac4f922-8239-4831-b23b-31426d0542c4"); + BOOST_CHECK_EQUAL (ciphers.front().not_valid_before(), "2013-07-06T20:04:58+00:00"); + BOOST_CHECK_EQUAL (ciphers.front().not_valid_after(), "2023-07-02T20:04:56+00:00"); + BOOST_CHECK_EQUAL (ciphers.front().key_data(), "8a2729c3e5b65c45d78305462104c3fb"); + + BOOST_CHECK_EQUAL (ciphers.back().cpl_id(), "eece17de-77e8-4a55-9347-b6bab5724b9f"); + BOOST_CHECK_EQUAL (ciphers.back().key_id(), "73baf5de-e195-4542-ab28-8a465f7d4079"); + BOOST_CHECK_EQUAL (ciphers.back().not_valid_before(), "2013-07-06T20:04:58+00:00"); + BOOST_CHECK_EQUAL (ciphers.back().not_valid_after(), "2023-07-02T20:04:56+00:00"); + BOOST_CHECK_EQUAL (ciphers.back().key_data(), "5327fb7ec2e807bd57059615bf8a169d"); +} diff --git a/test/tests.cc b/test/tests.cc index 4fc81571..49c6689f 100644 --- a/test/tests.cc +++ b/test/tests.cc @@ -70,6 +70,7 @@ wav (libdcp::Channel) static string test_corpus = "../libdcp-test"; +#include "kdm_test.cc" #include "decryption_test.cc" #include "dcp_test.cc" #include "error_test.cc" |
