Skip to content

Commit 08f9666

Browse files
committed
Throw error on invalid backup key
1 parent 90e1d6b commit 08f9666

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

contrib/bitcoin-core/src/util/strencodings.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,29 @@ bool IsHexNumber(const std::string& str)
8282
return (str.size() > starting_location);
8383
}
8484

85+
template <typename Byte>
86+
std::optional<std::vector<Byte>> TryParseHex(std::string_view str)
87+
{
88+
std::vector<Byte> vch;
89+
vch.reserve(str.size() / 2); // two hex characters form a single byte
90+
91+
auto it = str.begin();
92+
while (it != str.end()) {
93+
if (IsSpace(*it)) {
94+
++it;
95+
continue;
96+
}
97+
auto c1 = HexDigit(*(it++));
98+
if (it == str.end()) return std::nullopt;
99+
auto c2 = HexDigit(*(it++));
100+
if (c1 < 0 || c2 < 0) return std::nullopt;
101+
vch.push_back(Byte(c1 << 4) | Byte(c2));
102+
}
103+
return vch;
104+
}
105+
template std::optional<std::vector<std::byte>> TryParseHex(std::string_view);
106+
template std::optional<std::vector<uint8_t>> TryParseHex(std::string_view);
107+
85108
std::vector<unsigned char> ParseHex(const char* psz)
86109
{
87110
// convert hex dump to vector

contrib/bitcoin-core/src/util/strencodings.h

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include <cstdint>
1616
#include <iterator>
17+
#include <optional>
1718
#include <string>
1819
#include <vector>
1920

@@ -37,6 +38,9 @@ enum SafeChars
3738
std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT);
3839
std::vector<unsigned char> ParseHex(const char* psz);
3940
std::vector<unsigned char> ParseHex(const std::string& str);
41+
/** Parse the hex string into bytes (uint8_t or std::byte). Ignores whitespace. Returns nullopt on invalid input. */
42+
template <typename Byte = std::byte>
43+
std::optional<std::vector<Byte>> TryParseHex(std::string_view str);
4044
signed char HexDigit(char c);
4145
/* Returns true if each character in str is a hex character, and has an even
4246
* number of hex digits.*/

src/hwi_tapsigner.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <cctype>
33
#include <iostream>
44
#include <memory>
5+
#include <optional>
56
#include <string>
67
#include <vector>
78
#include <psbt.h>
@@ -497,12 +498,12 @@ std::string HWITapsignerImpl::DecryptBackup(const Bytes &encrypted_data,
497498
static constexpr unsigned char xprv[] = {'x', 'p', 'r', 'v'};
498499
static constexpr unsigned char tprv[] = {'t', 'p', 'r', 'v'};
499500

500-
const auto backup_key_bytes = ParseHex(backup_key);
501-
if (backup_key_bytes.size() != 16) {
501+
const auto opt_key_bytes = TryParseHex<unsigned char>(backup_key);
502+
if (!opt_key_bytes || opt_key_bytes->size() != 16) {
502503
throw TapProtoException(TapProtoException::INVALID_BACKUP_KEY,
503504
"Invalid backup key");
504505
}
505-
Bytes decrypted = AES128CTRDecrypt(encrypted_data, backup_key_bytes);
506+
Bytes decrypted = AES128CTRDecrypt(encrypted_data, *opt_key_bytes);
506507

507508
if (decrypted.size() < std::size(xprv)) {
508509
throw TapProtoException(TapProtoException::INVALID_BACKUP_KEY,

0 commit comments

Comments
 (0)