| // 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_Init(&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_ |