blob: 58d12ffcb67c2ee2d002a305705af5e4c4dfa2e9 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef U2FD_UTIL_H_
#define U2FD_UTIL_H_
#include <algorithm>
#include <string>
#include <vector>
#include <base/optional.h>
#include <base/logging.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/sha.h>
namespace u2f {
class TpmVendorCommandProxy;
namespace util {
// Utility functions for copying data to/from vector<uint8_t>.
// Utility function to copy an object, as raw bytes, to a vector.
template <typename FromType>
void AppendToVector(const FromType& from, std::vector<uint8_t>* to) {
const uint8_t* from_bytes = reinterpret_cast<const uint8_t*>(&from);
std::copy(from_bytes, from_bytes + sizeof(from), std::back_inserter(*to));
// Specializations of above function for copying from vector and string.
template <>
void AppendToVector(const std::vector<uint8_t>& from, std::vector<uint8_t>* to);
template <>
void AppendToVector(const std::string& from, std::vector<uint8_t>* to);
// Utility function to transform a string to a vector.
std::vector<uint8_t> ToVector(const std::string& str);
// Utility function to copy bytes from a vector to an object. This is the
// inverse of AppendToVector.
template <typename VectorAllocator, typename ToType>
bool VectorToObject(const std::vector<uint8_t, VectorAllocator>& from,
ToType* to,
const size_t size) {
if (size < from.size()) {
return false;
memcpy(to, &from.front(), from.size());
return true;
// Utility function to copy part of a string to a vector.
void AppendSubstringToVector(const std::string& from,
int start,
int length,
std::vector<uint8_t>* to);
// Crypto utilities.
// Attempts to convert the specified ECDSA signature (specified as r and s
// values) to DER encoding; returns base::nullopt on error.
base::Optional<std::vector<uint8_t>> SignatureToDerBytes(const uint8_t* r,
const uint8_t* s);
// Returns the SHA-256 of the specified data.
template <typename Blob>
std::vector<uint8_t> Sha256(const Blob& data) {
std::vector<uint8_t> hash(SHA256_DIGEST_LENGTH);
SHA256_CTX sha_context;
SHA256_Update(&sha_context, &data.front(), data.size());
SHA256_Final(&hash.front(), &sha_context);
return hash;
// Attest to |data_to_sign| using software attestation.
bool DoSoftwareAttest(const std::vector<uint8_t>& data_to_sign,
std::vector<uint8_t>* attestation_cert,
std::vector<uint8_t>* signature);
// Creates a new EC key to use for U2F attestation.
crypto::ScopedEC_KEY CreateAttestationKey();
// Signs data using attestion_key, and returns the DER-encoded signature,
// or base::nullopt on error.
base::Optional<std::vector<uint8_t>> AttestToData(
const std::vector<uint8_t>& data, EC_KEY* attestation_key);
// Returns an X509 certificate for the specified attestation_key, to be included
// in a U2F register response, or base::nullopt on error.
base::Optional<std::vector<uint8_t>> CreateAttestationCertificate(
EC_KEY* attestation_key);
// Parses the specified certificate and re-serializes it to the same vector,
// removing any padding that was present.
bool RemoveCertificatePadding(std::vector<uint8_t>* cert);
// Retrieves the G2F certificate from cr50. Returns nullopt on failure.
base::Optional<std::vector<uint8_t>> GetG2fCert(TpmVendorCommandProxy* proxy);
// Builds data to be signed as part of a U2F_REGISTER response, as defined by
// the "U2F Raw Message Formats" specification.
std::vector<uint8_t> BuildU2fRegisterResponseSignedData(
const std::vector<uint8_t>& app_id,
const std::vector<uint8_t>& challenge,
const std::vector<uint8_t>& pub_key,
const std::vector<uint8_t>& key_handle);
} // namespace util
} // namespace u2f
#endif // U2FD_UTIL_H_