blob: 66aa0646f4346a70df81817318fbf0555b55cb22 [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 {
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;
// 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);
} // namespace util
} // namespace u2f
#endif // U2FD_UTIL_H_