Parse a public key including origin information (if enabled). */
| 999 | |
| 1000 | /** Parse a public key including origin information (if enabled). */ |
| 1001 | std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) |
| 1002 | { |
| 1003 | using namespace spanparsing; |
| 1004 | |
| 1005 | auto origin_split = Split(sp, ']'); |
| 1006 | if (origin_split.size() > 2) { |
| 1007 | error = "Multiple ']' characters found for a single pubkey"; |
| 1008 | return nullptr; |
| 1009 | } |
| 1010 | if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, error); |
| 1011 | if (origin_split[0].empty() || origin_split[0][0] != '[') { |
| 1012 | error = strprintf("Key origin start '[ character expected but not found, got '%c' instead", |
| 1013 | origin_split[0].empty() ? /** empty, implies split char */ ']' : origin_split[0][0]); |
| 1014 | return nullptr; |
| 1015 | } |
| 1016 | auto slash_split = Split(origin_split[0].subspan(1), '/'); |
| 1017 | if (slash_split[0].size() != 8) { |
| 1018 | error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size()); |
| 1019 | return nullptr; |
| 1020 | } |
| 1021 | std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end()); |
| 1022 | if (!IsHex(fpr_hex)) { |
| 1023 | error = strprintf("Fingerprint '%s' is not hex", fpr_hex); |
| 1024 | return nullptr; |
| 1025 | } |
| 1026 | auto fpr_bytes = ParseHex(fpr_hex); |
| 1027 | KeyOriginInfo info; |
| 1028 | static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes"); |
| 1029 | assert(fpr_bytes.size() == 4); |
| 1030 | std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint); |
| 1031 | if (!ParseKeyPath(slash_split, info.path, error)) return nullptr; |
| 1032 | auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, error); |
| 1033 | if (!provider) return nullptr; |
| 1034 | return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider)); |
| 1035 | } |
| 1036 | |
| 1037 | /** Parse a script in a particular context. */ |
| 1038 | std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) |
no test coverage detected