Files
media_cas_packager_sdk_source/common/ec_key.h
2020-07-24 18:17:12 -07:00

176 lines
6.5 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// Copyright 2019 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
//
// Description:
// Generic elliptic curve classes for private and public keys. Declares
// methods for deriving shared session keys and signatures.
#ifndef COMMON_EC_KEY_H_
#define COMMON_EC_KEY_H_
#include <memory>
#include <string>
#include "absl/base/macros.h"
#include "openssl/ec.h"
#include "common/hash_algorithm.h"
#include "common/openssl_util.h"
namespace widevine {
class ECPublicKey;
class ECPrivateKey {
public:
explicit ECPrivateKey(EC_KEY* ec_key);
explicit ECPrivateKey(ScopedECKEY ec_key);
ECPrivateKey(const ECPrivateKey&);
ECPrivateKey() = delete;
virtual ~ECPrivateKey() = default;
// Accepted standard curves for key generation. Names are derived from SECG.
enum EllipticCurve {
UNDEFINED_CURVE = 0,
SECP256R1,
SECP384R1,
SECP521R1,
};
// Creates an ECPrivateKey using a DER encoded RFC5915 std::string
// representing a private key. Returns an ECPrivateKey on success or nullptr
// on failure.
static std::unique_ptr<ECPrivateKey> Create(
const std::string& serialized_key);
// Exports the matching public key for this private key.
virtual std::unique_ptr<ECPublicKey> PublicKey() const;
// Calculates a shared session key using ECDH and then uses a key derivation
// function, SHA256, to derive a key.
// |public_key| is an EC public key with the same curve parameters as key_. It
// is used as the public key component of ECDH.
// |derived_shared_session_key| will be the result of the derivation.
// Caller retains ownership of all pointers.
// Returns true on success and false on error.
virtual bool DeriveSharedSessionKey(
const ECPublicKey& public_key,
std::string* derived_shared_session_key) const;
// Given a message, calculates a signature using ECDSA with the key_.
// |message| is the message to be signed.
// |signature| will contain the resulting signature. This will be an ASN.1
// DER-encoded signature.
// Caller retains ownership of all pointers.
// Returns true on success and false on error.
// TODO(b/155438325): remove this function after the below function is fully
// propagated.
ABSL_DEPRECATED(
"Use the below function with |hash_algorithm| argument instead.")
virtual bool GenerateSignature(const std::string& message,
std::string* signature) const;
// Given a message, calculates a signature using ECDSA with the key_.
// |message| is the message to be signed.
// |hash_algorithm| specifies the hash algorithm.
// |signature| will contain the resulting signature. This will be an ASN.1
// DER-encoded signature.
// Caller retains ownership of all pointers.
// Returns true on success and false on error.
virtual bool GenerateSignature(const std::string& message,
HashAlgorithm hash_algorithm,
std::string* signature) const;
// Returns whether the given private key is the same as key_.
virtual bool MatchesPrivateKey(const ECPrivateKey& private_key) const;
// Returns whether the given public key is part of the same key pair as key_.
virtual bool MatchesPublicKey(const ECPublicKey& public_key) const;
// Returns the EllipticCurve associated with key_.
virtual EllipticCurve Curve() const;
virtual bool SerializedKey(std::string* serialized_key) const;
private:
friend class ECPublicKey;
ECPrivateKey& operator=(const ECPrivateKey&) = delete;
const EC_KEY* key() const { return key_.get(); }
ScopedECKEY key_;
};
class ECPublicKey {
public:
explicit ECPublicKey(EC_KEY* ec_key);
explicit ECPublicKey(ScopedECKEY ec_key);
ECPublicKey(const ECPublicKey&);
virtual ~ECPublicKey() = default;
// Creates an ECPublicKey using a DER encoded RFC5208 std::string representing
// a public key. Returns an ECPublicKey on success or nullptr on failure.
static std::unique_ptr<ECPublicKey> Create(const std::string& serialized_key);
// Creates an ECPublicKey from an uncompressed point compatible with X9.62.
// Returns an ECPublicKey on success or nullptr on failure.
static std::unique_ptr<ECPublicKey> CreateFromKeyPoint(
ECPrivateKey::EllipticCurve curve, const std::string& key_point);
// Given a message and a signature, verifies that the signature was created
// using the private key associated with key_.
// |message| is the message that was signed.
// |signature| is an ASN.1 DER-encoded signature.
// Returns true on success and false on error.
// TODO(b/155438325): remove this function after the below function is fully
// propagated.
ABSL_DEPRECATED(
"Use the below function with |hash_algorithm| argument instead.")
virtual bool VerifySignature(const std::string& message,
const std::string& signature) const;
// Given a message and a signature, verifies that the signature was created
// using the private key associated with key_.
// |message| is the message that was signed.
// |hash_algorithm| specifies the hash algorithm.
// |signature| is an ASN.1 DER-encoded signature.
// Returns true on success and false on error.
virtual bool VerifySignature(const std::string& message,
HashAlgorithm hash_algorithm,
const std::string& signature) const;
// Returns whether the given private key is part of the same key pair as key_.
virtual bool MatchesPrivateKey(const ECPrivateKey& private_key) const;
// Returns whether the given public key is the same as key_.
virtual bool MatchesPublicKey(const ECPublicKey& public_key) const;
// Returns the EllipticCurve associated with key_.
virtual ECPrivateKey::EllipticCurve Curve() const;
virtual bool SerializedKey(std::string* serialized_key) const;
// Returns the key in the uncompressed point format. Compatible with X9.62
// The lead byte indicates uncompressed format (0x4). This is followed by the
// octets for the X and Y coordinates.
virtual bool GetPointEncodedKey(std::string* encoded_key) const;
private:
friend class ECPrivateKey;
ECPublicKey& operator=(const ECPublicKey&) = delete;
const EC_KEY* key() const { return key_.get(); }
ScopedECKEY key_;
};
} // namespace widevine
#endif // COMMON_EC_KEY_H_