blob: 3a5976cb4e9981f0e0ec667821046ec2e4f47a2f [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.
#include "u2fd/util.h"
#include <string>
#include <vector>
#include <base/logging.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/sha.h>
namespace u2f {
namespace util {
template <>
void AppendToVector(const std::vector<uint8_t>& from,
std::vector<uint8_t>* to) {
to->insert(to->end(), from.begin(), from.end());
}
template <>
void AppendToVector(const std::string& from, std::vector<uint8_t>* to) {
to->insert(to->end(), from.begin(), from.end());
}
void AppendSubstringToVector(const std::string& from,
int start,
int length,
std::vector<uint8_t>* to) {
to->insert(to->end(), from.begin() + start, from.begin() + start + length);
}
base::Optional<std::vector<uint8_t>> SignatureToDerBytes(const uint8_t* r,
const uint8_t* s) {
crypto::ScopedECDSA_SIG sig(ECDSA_SIG_new());
if (!BN_bin2bn(r, 32, sig->r) || !BN_bin2bn(s, 32, sig->s)) {
LOG(ERROR) << "Failed to initialize ECDSA_SIG";
return base::nullopt;
}
int sig_len = i2d_ECDSA_SIG(sig.get(), nullptr);
std::vector<uint8_t> signature(sig_len);
uint8_t* sig_ptr = &signature[0];
if (i2d_ECDSA_SIG(sig.get(), &sig_ptr) != sig_len) {
LOG(ERROR) << "DER encoding returned unexpected length";
return base::nullopt;
}
return signature;
}
std::vector<uint8_t> Sha256(const std::vector<uint8_t>& 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;
}
} // namespace util
} // namespace u2f