X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fdecrypted_ecinema_kdm.cc;h=f76161c8b6a2dec461040913abc94a8d320b0df0;hb=a7cd9cec31952b932ab80fb50cddec28aab74736;hp=2cb4f61d7a3ece135d9894ae2e3ae756358d18fd;hpb=63bab3a5f4abc7c5ef8562f3048b55cb3a24c71f;p=dcpomatic.git diff --git a/src/lib/decrypted_ecinema_kdm.cc b/src/lib/decrypted_ecinema_kdm.cc index 2cb4f61d7..f76161c8b 100644 --- a/src/lib/decrypted_ecinema_kdm.cc +++ b/src/lib/decrypted_ecinema_kdm.cc @@ -22,21 +22,80 @@ #include "encrypted_ecinema_kdm.h" #include "decrypted_ecinema_kdm.h" +#include "ecinema_kdm_data.h" +#include "exceptions.h" +#include "compose.hpp" #include +#include #include +#include +#include +#include +using std::string; +using std::runtime_error; using dcp::Certificate; +using boost::optional; -DecryptedECinemaKDM::DecryptedECinemaKDM (dcp::Key content_key) - : _content_key (content_key) +DecryptedECinemaKDM::DecryptedECinemaKDM (string id, string name, dcp::Key content_key, optional not_valid_before, optional not_valid_after) + : _id (id) + , _name (name) + , _content_key (content_key) + , _not_valid_before (not_valid_before) + , _not_valid_after (not_valid_after) { } +DecryptedECinemaKDM::DecryptedECinemaKDM (EncryptedECinemaKDM kdm, string private_key) + : _id (kdm.id()) + , _name (kdm.name()) +{ + /* Read the private key */ + + BIO* bio = BIO_new_mem_buf (const_cast (private_key.c_str()), -1); + if (!bio) { + throw runtime_error ("could not create memory BIO"); + } + + RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0); + if (!rsa) { + throw FileError ("could not read RSA private key file", private_key); + } + + uint8_t value[RSA_size(rsa)]; + int const len = RSA_private_decrypt (kdm.data().size(), kdm.data().data().get(), value, rsa, RSA_PKCS1_OAEP_PADDING); + if (len == -1) { + throw KDMError (ERR_error_string(ERR_get_error(), 0), ""); + } + + if (len != ECINEMA_KDM_KEY_LENGTH && len != (ECINEMA_KDM_KEY_LENGTH + ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH + ECINEMA_KDM_NOT_VALID_AFTER_LENGTH)) { + throw KDMError ( + "Unexpected data block size in ECinema KDM.", + String::compose("Size was %1; expected %2 or %3", ECINEMA_KDM_KEY_LENGTH, ECINEMA_KDM_KEY_LENGTH + ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH + ECINEMA_KDM_NOT_VALID_AFTER_LENGTH) + ); + } + + _content_key = dcp::Key (value + ECINEMA_KDM_KEY, ECINEMA_KDM_KEY_LENGTH); + if (len > ECINEMA_KDM_KEY_LENGTH) { + uint8_t* p = value + ECINEMA_KDM_NOT_VALID_BEFORE; + string b; + for (int i = 0; i < ECINEMA_KDM_NOT_VALID_BEFORE_LENGTH; ++i) { + b += *p++; + } + _not_valid_before = dcp::LocalTime (b); + string a; + for (int i = 0; i < ECINEMA_KDM_NOT_VALID_AFTER_LENGTH; ++i) { + a += *p++; + } + _not_valid_after = dcp::LocalTime (a); + } +} + EncryptedECinemaKDM DecryptedECinemaKDM::encrypt (Certificate recipient) { - return EncryptedECinemaKDM (_content_key, recipient); + return EncryptedECinemaKDM (_id, _name, _content_key, _not_valid_before, _not_valid_after, recipient); } #endif