@@ -587,7 +587,8 @@ static void node_free(ms_node *node)
587587 node_free (child );
588588 child = next ;
589589 }
590- if (node -> kind & (KIND_RAW | KIND_ADDRESS ) || node -> kind == KIND_PUBLIC_KEY || node -> kind == KIND_PRIVATE_KEY )
590+ if (node -> kind & (KIND_RAW | KIND_ADDRESS ) ||
591+ node -> kind == KIND_PUBLIC_KEY || node -> kind == KIND_PRIVATE_KEY )
591592 clear_and_free ((void * )node -> data , node -> data_len );
592593 clear_and_free (node , sizeof (* node ));
593594 }
@@ -2249,58 +2250,80 @@ static int analyze_address(ms_ctx *ctx, const char *str, size_t str_len,
22492250 return ret ;
22502251}
22512252
2252- /* take the possible hex data in node->data, if it is a valid pubkey
2253+ /* take the possible hex data in node->data, if it is a valid key then
22532254 * convert it to an allocated binary buffer and make this node a key node
22542255 */
2255- static int analyze_pubkey_hex (ms_ctx * ctx , ms_node * node ,
2256- uint32_t flags , bool * is_hex )
2257- {
2258- unsigned char pubkey [EC_PUBLIC_KEY_UNCOMPRESSED_LEN ];
2259- size_t pubkey_len ;
2260- bool allow_xonly , make_xonly = false;
2261-
2262- * is_hex = wally_hex_n_to_bytes (node -> data , node -> data_len ,
2263- pubkey , sizeof (pubkey ), & pubkey_len ) == WALLY_OK ;
2264- if (!* is_hex || pubkey_len > sizeof (pubkey ))
2265- return WALLY_OK ; /* Not hex, or too long */
2266-
2267- if (wally_ec_public_key_verify (pubkey , pubkey_len ) != WALLY_OK &&
2268- wally_ec_xonly_public_key_verify (pubkey , pubkey_len ) != WALLY_OK )
2269- return WALLY_OK ; /* Not a valid pubkey */
2270-
2271- make_xonly = node -> parent &&
2272- (node -> parent -> kind == KIND_DESCRIPTOR_RAW_TR ||
2273- node -> parent -> kind == KIND_DESCRIPTOR_TR );
2274- allow_xonly = make_xonly || flags & WALLY_MINISCRIPT_TAPSCRIPT ;
2275- if (pubkey_len == EC_PUBLIC_KEY_UNCOMPRESSED_LEN && allow_xonly )
2276- return WALLY_OK ; /* Uncompressed key not allowed here */
2277- if (pubkey_len == EC_XONLY_PUBLIC_KEY_LEN && !allow_xonly )
2278- return WALLY_OK ; /* X-only not allowed here */
2279- if (pubkey_len != EC_XONLY_PUBLIC_KEY_LEN ) {
2280- if (flags & WALLY_MINISCRIPT_TAPSCRIPT )
2281- return WALLY_OK ; /* Only X-only pubkeys allowed under tapscript */
2282- if (make_xonly ) {
2283- /* Convert to x-only */
2284- -- pubkey_len ;
2285- memmove (pubkey , pubkey + 1 , pubkey_len );
2256+ static int analyze_key_hex (ms_ctx * ctx , ms_node * node ,
2257+ uint32_t flags , bool is_ct_key , bool * is_hex )
2258+ {
2259+ unsigned char key [EC_PUBLIC_KEY_UNCOMPRESSED_LEN ], * key_p = key ;
2260+ size_t key_len ;
2261+ bool allow_xonly , make_xonly = false, is_private = false;
2262+
2263+ * is_hex = wally_hex_n_to_bytes (node -> data , node -> data_len ,
2264+ key , sizeof (key ), & key_len ) == WALLY_OK ;
2265+ if (!* is_hex )
2266+ return WALLY_OK ; /* Not a hex string */
2267+
2268+ if (key_len == EC_PRIVATE_KEY_LEN && is_ct_key ) {
2269+ if (wally_ec_private_key_verify (key , key_len ) != WALLY_OK )
2270+ return WALLY_OK ; /* Not a valid private key */
2271+ is_private = true;
2272+ } else if (key_len == EC_XONLY_PUBLIC_KEY_LEN ) {
2273+ if (wally_ec_xonly_public_key_verify (key , key_len ) != WALLY_OK )
2274+ return WALLY_OK ; /* Not a valid x-only key */
2275+ } else if (key_len == EC_PUBLIC_KEY_LEN ||
2276+ key_len == EC_PUBLIC_KEY_UNCOMPRESSED_LEN ) {
2277+ if (wally_ec_public_key_verify (key , key_len ) != WALLY_OK )
2278+ return WALLY_OK ; /* Not a valid compressed/uncompressed pubkey */
2279+ } else
2280+ return WALLY_OK ; /* Not a pubkey */
2281+
2282+ if (!is_private ) {
2283+ /* Ensure the pubkey is allowed in this context/convert as needed */
2284+ make_xonly = node -> parent &&
2285+ (node -> parent -> kind == KIND_DESCRIPTOR_RAW_TR ||
2286+ node -> parent -> kind == KIND_DESCRIPTOR_TR );
2287+ allow_xonly = make_xonly || flags & WALLY_MINISCRIPT_TAPSCRIPT ;
2288+ if (key_len == EC_PUBLIC_KEY_UNCOMPRESSED_LEN && allow_xonly )
2289+ return WALLY_OK ; /* Uncompressed key not allowed here */
2290+ if (key_len == EC_XONLY_PUBLIC_KEY_LEN && !allow_xonly )
2291+ return WALLY_OK ; /* X-only not allowed here */
2292+ if (key_len != EC_XONLY_PUBLIC_KEY_LEN ) {
2293+ if (flags & WALLY_MINISCRIPT_TAPSCRIPT )
2294+ return WALLY_OK ; /* Only X-only pubkeys allowed under tapscript */
2295+ if (make_xonly ) {
2296+ /* Convert to x-only */
2297+ -- key_len ;
2298+ ++ key_p ;
2299+ }
22862300 }
22872301 }
22882302
2289- if (!clone_bytes ((unsigned char * * )& node -> data , pubkey , pubkey_len ))
2303+ if (!clone_bytes ((unsigned char * * )& node -> data , key_p , key_len ))
22902304 return WALLY_ENOMEM ;
2291- node -> data_len = pubkey_len ;
2305+ node -> data_len = key_len ;
22922306
2293- if (pubkey_len == EC_PUBLIC_KEY_UNCOMPRESSED_LEN ) {
2307+ if (is_ct_key )
2308+ ctx -> features |= WALLY_MS_IS_ELIP150 ;
2309+ if (is_private ) {
2310+ node -> kind = KIND_PRIVATE_KEY ;
2311+ node -> flags |= (WALLY_MS_IS_PRIVATE | WALLY_MS_IS_RAW );
2312+ return WALLY_OK ;
2313+ }
2314+ node -> kind = KIND_PUBLIC_KEY ;
2315+ if (is_ct_key )
2316+ return WALLY_OK ;
2317+ if (key_len == EC_PUBLIC_KEY_UNCOMPRESSED_LEN ) {
22942318 node -> flags |= WALLY_MS_IS_UNCOMPRESSED ;
22952319 ctx -> features |= WALLY_MS_IS_UNCOMPRESSED ;
22962320 }
2297- if (pubkey_len == EC_XONLY_PUBLIC_KEY_LEN ) {
2321+ if (key_len == EC_XONLY_PUBLIC_KEY_LEN ) {
22982322 node -> flags |= WALLY_MS_IS_X_ONLY ;
22992323 ctx -> features |= WALLY_MS_IS_X_ONLY ;
23002324 }
2301- ctx -> features |= WALLY_MS_IS_RAW ;
2302- node -> kind = KIND_PUBLIC_KEY ;
23032325 node -> flags |= WALLY_MS_IS_RAW ;
2326+ ctx -> features |= WALLY_MS_IS_RAW ;
23042327 return ctx_add_key_node (ctx , node );
23052328}
23062329
@@ -2357,8 +2380,8 @@ static int analyze_miniscript_key(ms_ctx *ctx, uint32_t flags,
23572380 node -> data_len -= size ;
23582381 }
23592382
2360- /* Check for a hex public key */
2361- ret = analyze_pubkey_hex (ctx , node , flags , & is_hex );
2383+ /* Check for a hex public key (hex private keys allowed for ct() only) */
2384+ ret = analyze_key_hex (ctx , node , flags , is_ct_key , & is_hex );
23622385 if (ret == WALLY_OK && is_hex )
23632386 return WALLY_OK ;
23642387
0 commit comments