From cf0733dc6fc7ce274ac17561fe10c1e068f63bc0 Mon Sep 17 00:00:00 2001 From: David C Goldenberg Date: Thu, 19 Jun 2025 09:41:52 -0400 Subject: [PATCH] Update after QA. Added a function in Bitcoin.mjs to return valid extended key versions, which is now used in SeedToMPK, KeyToExtendedKey and ChangeExtendedKeyVersion. This will make sure only valid version options are given. Also added some input sanitization code to deal with blank input. --- src/core/lib/Bitcoin.mjs | 8 +++++++- src/core/operations/ChangeExtendedKeyVersion.mjs | 5 +++-- src/core/operations/KeyToExtendedKey.mjs | 9 +++++++-- src/core/operations/SeedToMPK.mjs | 13 +++++-------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/core/lib/Bitcoin.mjs b/src/core/lib/Bitcoin.mjs index c65699d7..89e229e8 100644 --- a/src/core/lib/Bitcoin.mjs +++ b/src/core/lib/Bitcoin.mjs @@ -28,7 +28,7 @@ function validateLengths(input, allowableLengths) { * Returns true if input is a valid hex string, false otherwise. * @param {*} input */ -function isHex(input) { +export function isHex(input) { const re = /^[0-9A-Fa-f]{2,}$/g; return re.test(input) && input.length %2 === 0; } @@ -467,6 +467,12 @@ export function getExtendedKeyString(input) { return versionString[input]; } +/** + * Returns valid versions as an array. + */ +export function getVersions() { + return Object.keys(versionBytes); +} /** * We serialize the extended key based off of the passed in data. diff --git a/src/core/operations/ChangeExtendedKeyVersion.mjs b/src/core/operations/ChangeExtendedKeyVersion.mjs index 7f367f5d..94561f5d 100644 --- a/src/core/operations/ChangeExtendedKeyVersion.mjs +++ b/src/core/operations/ChangeExtendedKeyVersion.mjs @@ -7,7 +7,7 @@ */ import Operation from "../Operation.mjs"; -import { deserializeExtendedKeyFunc, serializeExtendedKeyFunc, getExtendedKeyVersion } from "../lib/Bitcoin.mjs"; +import { deserializeExtendedKeyFunc, serializeExtendedKeyFunc, getExtendedKeyVersion, getVersions } from "../lib/Bitcoin.mjs"; /** @@ -31,7 +31,8 @@ class ChangeExtendedKeyVersion extends Operation { { "name": "Version Type", "type": "option", - "value": ["xpub", "xprv", "ypub", "yprv", "zpub", "zprv", "Zpub", "Zprv", "Ypub", "Yprv", "Ltub", "Ltpv", "Mtub", "Mtpv", "ttub", "ttpv", "tpub", "tprv", "upub", "uprv", "vpub", "vprv", "Upub", "Uprv", "Vpub", "Vprv"] + "value": getVersions() + // "value": ["xpub", "xprv", "ypub", "yprv", "zpub", "zprv", "Zpub", "Zprv", "Ypub", "Yprv", "Ltub", "Ltpv", "Mtub", "Mtpv", "ttub", "ttpv", "tpub", "tprv", "upub", "uprv", "vpub", "vprv", "Upub", "Uprv", "Vpub", "Vprv"] } ]; this.checks = [ diff --git a/src/core/operations/KeyToExtendedKey.mjs b/src/core/operations/KeyToExtendedKey.mjs index b5b168b2..7c6a1f84 100644 --- a/src/core/operations/KeyToExtendedKey.mjs +++ b/src/core/operations/KeyToExtendedKey.mjs @@ -6,7 +6,7 @@ import Operation from "../Operation.mjs"; import OperationError from "../errors/OperationError.mjs"; -import { makeSureIsHex, serializeExtendedKeyFunc, getExtendedKeyVersion } from "../lib/Bitcoin.mjs"; +import { makeSureIsHex, serializeExtendedKeyFunc, getExtendedKeyVersion, getVersions } from "../lib/Bitcoin.mjs"; /** @@ -36,7 +36,8 @@ class KeyToExtendedKey extends Operation { { "name": "Version Type", "type": "option", - "value": ["xpub", "xprv", "ypub", "yprv", "zpub", "zprv", "Zpub", "Zprv", "Ypub", "Yprv", "Ltub", "Ltpv", "Mtub", "Mtpv", "ttub", "ttpv", "tpub", "tprv", "upub", "uprv", "vpub", "vprv", "Upub", "Uprv", "Vpub", "Vprv"] + "value": getVersions() + // "value": ["xpub", "xprv", "ypub", "yprv", "zpub", "zprv", "Zpub", "Zprv", "Ypub", "Yprv", "Ltub", "Ltpv", "Mtub", "Mtpv", "ttub", "ttpv", "tpub", "tprv", "upub", "uprv", "vpub", "vprv", "Upub", "Uprv", "Vpub", "Vprv"] } /* Example arguments. See the project wiki for full details. { @@ -60,6 +61,10 @@ class KeyToExtendedKey extends Operation { */ run(input, args) { // const [firstArg, secondArg] = args; + if (input.trim().length === 0) { + return ""; + } + input = input.trim(); const inputAsHex = makeSureIsHex(input); const isPublic = inputAsHex.length === 66 && (inputAsHex.startsWith("03") || inputAsHex.startsWith("02")); diff --git a/src/core/operations/SeedToMPK.mjs b/src/core/operations/SeedToMPK.mjs index 23f6f878..96182674 100644 --- a/src/core/operations/SeedToMPK.mjs +++ b/src/core/operations/SeedToMPK.mjs @@ -7,7 +7,7 @@ */ import Operation from "../Operation.mjs"; -import { serializeExtendedKeyFunc, getExtendedKeyVersion } from "../lib/Bitcoin.mjs"; +import { serializeExtendedKeyFunc, getExtendedKeyVersion, getVersions, isHex } from "../lib/Bitcoin.mjs"; import forge from "node-forge"; import Utils from "../Utils.mjs"; @@ -33,7 +33,8 @@ class SeedToMPK extends Operation { { "name": "Version Type", "type": "option", - "value": ["xprv", "yprv", "zprv", "Zprv", "Yprv", "Ltpv", "Mtpv", "ttpv", "tprv", "uprv", "vprv", "Uprv", "Vprv"] + "value": getVersions() + // "value": ["xprv", "yprv", "zprv", "Zprv", "Yprv", "Ltpv", "Mtpv", "ttpv", "tprv", "uprv", "vprv", "Uprv", "Vprv"] } ]; } @@ -50,15 +51,11 @@ class SeedToMPK extends Operation { input = input.trim(); - // We check to see if the input is hex or not. - // If it is not, we convert it back to hex - const re = /^[0-9A-Fa-f]{2,}$/g; - const isHex = re.test(input) && input.length %2 === 0; - + const isItHex = isHex(input); // Create the hmac. const hmac = forge.hmac.create(); hmac.start("sha512", Utils.convertToByteString("Bitcoin seed", "UTF8")); - if (isHex) { + if (isItHex) { hmac.update(Utils.convertToByteString(input, "hex")); } else { hmac.update(input);