151 lines
5.3 KiB
C++
151 lines
5.3 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.
|
|
// |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.
|
|
// |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_
|