Add test base that catches nonce flood

Merge from Widevine repo of http://go/wvgerrit/56520

This CL adds a test base that installs a test keybox and catches nonce
flood errors for all CDM tests.

In order to do this, a new class is added called a
CryptoSessionFactory.  The default factory just creates a new
CryptoSession.  All places in the code that create a new CryptoSession
now call the static method MakeCryptoSession, which uses the current
factory to create a CryptoSession.  If MakeCryptoSession is called and
there is no current factory, a default factory is created.

The CryptoSession constructor is now private, so that we do not
accidentally try to create one without using the factory.

For the new test base, we first create a special test
CryptoSessionFactory that creates a TestCryptoSession.  The test
factory catches the first call to MakeCryptoSession and injects an
installation of the test keybox after OEMCrypto_Initialize is called.

The TestCryptoSession injects a sleep statement and a retry whenever
it detects a nonce flood.

Test: current unit tests still pass.
bug: 72354901 Fix Generic Crypto tests.
bug: 111361440 Remove #ifdef from unit tests
Change-Id: I248e7f3c53721c04d2af412ef835e19bb4d15d9a
This commit is contained in:
Fred Gylys-Colwell
2018-08-03 17:08:09 -07:00
parent c06b55b42f
commit 4af5aaf18a
24 changed files with 305 additions and 151 deletions

View File

@@ -26,7 +26,7 @@ class ServiceCertificate;
class CertificateProvisioning {
public:
CertificateProvisioning(metrics::CryptoMetrics* metrics) :
crypto_session_(metrics),
crypto_session_(CryptoSession::MakeCryptoSession(metrics)),
cert_type_(kCertificateWidevine),
service_certificate_(new ServiceCertificate()) {}
~CertificateProvisioning() {}
@@ -53,7 +53,7 @@ class CertificateProvisioning {
video_widevine::SignedProvisioningMessage::ProtocolVersion
GetProtocolVersion();
CryptoSession crypto_session_;
scoped_ptr<CryptoSession> crypto_session_;
CdmCertificateType cert_type_;
scoped_ptr<ServiceCertificate> service_certificate_;

View File

@@ -34,6 +34,8 @@ void GenerateEncryptContext(const std::string& input_context,
size_t GetOffset(std::string message, std::string field);
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode);
class CryptoSessionFactory;
class CryptoSession {
public:
typedef OEMCrypto_HDCP_Capability HdcpCapability;
@@ -52,7 +54,9 @@ class CryptoSession {
// Creates an instance of CryptoSession with the given |crypto_metrics|.
// |crypto_metrics| is owned by the caller, must NOT be null, and must
// exist as long as the new CryptoSession exists.
explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics);
static CryptoSession* MakeCryptoSession(
metrics::CryptoMetrics* crypto_metrics);
virtual ~CryptoSession();
virtual bool GetProvisioningToken(std::string* client_token);
@@ -203,8 +207,26 @@ class CryptoSession {
SecurityLevel requested_security_level,
CdmClientTokenType* token_type);
protected:
// Creates an instance of CryptoSession with the given |crypto_metrics|.
// |crypto_metrics| is owned by the caller, must NOT be null, and must
// exist as long as the new CryptoSession exists.
explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics);
int session_count() { return session_count_; }
private:
friend class CryptoSessionForTest;
friend class CryptoSessionFactory;
friend class WvCdmTestBase;
// The global factory method can be set to generate special crypto sessions
// just for testing. These sessions will avoid nonce floods and will ask
// OEMCrypto to use a test keybox.
// Ownership of the object is transfered to CryptoSession.
static void SetCryptoSessionFactory(CryptoSessionFactory* factory) {
factory_.reset(factory);
}
void Init();
void Terminate();
@@ -291,9 +313,25 @@ class CryptoSession {
CdmCipherMode cipher_mode_;
uint32_t api_version_;
static scoped_ptr<CryptoSessionFactory> factory_;
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession);
};
class CryptoSessionFactory {
public:
virtual ~CryptoSessionFactory() {}
virtual CryptoSession* MakeCryptoSession(
metrics::CryptoMetrics* crypto_metrics);
protected:
friend class CryptoSession;
CryptoSessionFactory() {}
private:
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSessionFactory);
};
} // namespace wvcdm
#endif // WVCDM_CORE_CRYPTO_SESSION_H_

View File

@@ -18,6 +18,7 @@
#include "disallow_copy_and_assign.h"
#include "license_protocol.pb.h"
#include "privacy_crypto.h"
#include "scoped_ptr.h"
#include "wv_cdm_types.h"
namespace wvcdm {
@@ -78,7 +79,7 @@ class ServiceCertificate {
std::string provider_id_;
// Public key.
std::auto_ptr<RsaPublicKey> public_key_;
scoped_ptr<RsaPublicKey> public_key_;
CORE_DISALLOW_COPY_AND_ASSIGN(ServiceCertificate);
};