mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-22 16:44:20 +01:00
lightningd: remove getsharedsecret.
This was introduced to allow creating a shared secret, but it's better to use makesecret which creates unique secrets. getsharedsecret being a generic ECDH function allows the caller to initiate conversations as if it was us; this is generally OK, since we don't allow untrusted API access, but the commando plugin had to blacklist this for read-only runes explicitly. Since @ZmnSCPxj never ended up using this after introducing it, simply remove it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Removed: JSONRPC: `getsharedsecret` API: use `makesecret`
This commit is contained in:
@@ -93,7 +93,6 @@ def load_jsonrpc_service(schema_dir: str = None):
|
|||||||
# "funderupdate",
|
# "funderupdate",
|
||||||
# "getlog",
|
# "getlog",
|
||||||
"GetRoute",
|
"GetRoute",
|
||||||
# "getsharedsecret",
|
|
||||||
"ListForwards",
|
"ListForwards",
|
||||||
# "listoffers",
|
# "listoffers",
|
||||||
"ListPays",
|
"ListPays",
|
||||||
|
|||||||
@@ -1442,18 +1442,6 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
}
|
}
|
||||||
return self.call("checkmessage", payload)
|
return self.call("checkmessage", payload)
|
||||||
|
|
||||||
def getsharedsecret(self, point, **kwargs):
|
|
||||||
"""
|
|
||||||
Compute the hash of the Elliptic Curve Diffie Hellman shared
|
|
||||||
secret point from this node private key and an
|
|
||||||
input {point}.
|
|
||||||
"""
|
|
||||||
payload = {
|
|
||||||
"point": point
|
|
||||||
}
|
|
||||||
payload.update({k: v for k, v in kwargs.items()})
|
|
||||||
return self.call("getsharedsecret", payload)
|
|
||||||
|
|
||||||
def keysend(self, destination, amount_msat=None, label=None, maxfeepercent=None,
|
def keysend(self, destination, amount_msat=None, label=None, maxfeepercent=None,
|
||||||
retry_for=None, maxdelay=None, exemptfee=None,
|
retry_for=None, maxdelay=None, exemptfee=None,
|
||||||
extratlvs=None, msatoshi=None):
|
extratlvs=None, msatoshi=None):
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ MANPAGES := doc/lightning-cli.1 \
|
|||||||
doc/lightning-funderupdate.7 \
|
doc/lightning-funderupdate.7 \
|
||||||
doc/lightning-fundpsbt.7 \
|
doc/lightning-fundpsbt.7 \
|
||||||
doc/lightning-getroute.7 \
|
doc/lightning-getroute.7 \
|
||||||
doc/lightning-getsharedsecret.7 \
|
|
||||||
doc/lightning-hsmtool.8 \
|
doc/lightning-hsmtool.8 \
|
||||||
doc/lightning-invoice.7 \
|
doc/lightning-invoice.7 \
|
||||||
doc/lightning-keysend.7 \
|
doc/lightning-keysend.7 \
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ Core Lightning Documentation
|
|||||||
lightning-getinfo <lightning-getinfo.7.md>
|
lightning-getinfo <lightning-getinfo.7.md>
|
||||||
lightning-getlog <lightning-getlog.7.md>
|
lightning-getlog <lightning-getlog.7.md>
|
||||||
lightning-getroute <lightning-getroute.7.md>
|
lightning-getroute <lightning-getroute.7.md>
|
||||||
lightning-getsharedsecret <lightning-getsharedsecret.7.md>
|
|
||||||
lightning-help <lightning-help.7.md>
|
lightning-help <lightning-help.7.md>
|
||||||
lightning-hsmtool <lightning-hsmtool.8.md>
|
lightning-hsmtool <lightning-hsmtool.8.md>
|
||||||
lightning-invoice <lightning-invoice.7.md>
|
lightning-invoice <lightning-invoice.7.md>
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
lightning-getsharedsecret -- Command for computing an ECDH
|
|
||||||
==========================================================
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
--------
|
|
||||||
|
|
||||||
**getsharedsecret** *point*
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The **getsharedsecret** RPC command computes a shared secret from a
|
|
||||||
given public *point*, and the secret key of this node.
|
|
||||||
The *point* is a hexadecimal string of the compressed public
|
|
||||||
key DER-encoding of the SECP256K1 point.
|
|
||||||
|
|
||||||
RETURN VALUE
|
|
||||||
------------
|
|
||||||
|
|
||||||
[comment]: # (GENERATE-FROM-SCHEMA-START)
|
|
||||||
On success, an object is returned, containing:
|
|
||||||
- **shared_secret** (hex): the SHA-2 of the compressed encoding of the shared secp256k1 point (always 64 characters)
|
|
||||||
|
|
||||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
|
||||||
|
|
||||||
This command may fail if communications with the HSM has a
|
|
||||||
problem;
|
|
||||||
by default lightningd uses a software "HSM" which should
|
|
||||||
never fail in this way.
|
|
||||||
(As of the time of this writing there is no true hardware
|
|
||||||
HSM that lightningd can use, but we are leaving this
|
|
||||||
possibilty open in the future.)
|
|
||||||
In that case, it will return with an error code of 800.
|
|
||||||
|
|
||||||
CRYPTOGRAPHIC STANDARDS
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
This serves as a key agreement scheme in elliptic-curve based
|
|
||||||
cryptographic standards.
|
|
||||||
|
|
||||||
However, note that most key agreement schemes based on
|
|
||||||
Elliptic-Curve Diffie-Hellman do not hash the DER-compressed
|
|
||||||
point.
|
|
||||||
Standards like SECG SEC-1 ECIES specify using the X coordinate
|
|
||||||
of the point instead.
|
|
||||||
The Lightning BOLT standard (which `lightningd` uses), unlike
|
|
||||||
most other cryptographic standards, specifies the SHA-256 hash
|
|
||||||
of the DER-compressed encoding of the point.
|
|
||||||
|
|
||||||
It is not possible to extract the X coordinate of the ECDH point
|
|
||||||
via this API, since there is no known way to reverse the 256-bit
|
|
||||||
SHA-2 hash function.
|
|
||||||
Thus there is no way to implement ECIES and similar standards using
|
|
||||||
this API.
|
|
||||||
|
|
||||||
If you know the secret key behind *point*, you do not need to
|
|
||||||
even call **getsharedsecret**, you can just multiply the secret key
|
|
||||||
with the node public key.
|
|
||||||
|
|
||||||
Typically, a sender will generate an ephemeral secret key
|
|
||||||
and multiply it with the node public key,
|
|
||||||
then use the result to derive an encryption key
|
|
||||||
for a symmetric encryption scheme
|
|
||||||
to encrypt a message that can be read only by that node.
|
|
||||||
Then the ephemeral secret key is multiplied
|
|
||||||
by the standard generator point,
|
|
||||||
and the ephemeral public key and the encrypted message is
|
|
||||||
sent to the node,
|
|
||||||
which then uses **getsharedsecret** to derive the same key.
|
|
||||||
|
|
||||||
The above sketch elides important details like
|
|
||||||
key derivation function, stream encryption scheme,
|
|
||||||
message authentication code, and so on.
|
|
||||||
You should follow an established standard and avoid
|
|
||||||
rolling your own crypto.
|
|
||||||
|
|
||||||
AUTHOR
|
|
||||||
------
|
|
||||||
|
|
||||||
ZmnSCPxj <<ZmnSCPxj@protonmail.com>> is mainly responsible.
|
|
||||||
|
|
||||||
SEE ALSO
|
|
||||||
--------
|
|
||||||
|
|
||||||
RESOURCES
|
|
||||||
---------
|
|
||||||
|
|
||||||
* BOLT 4: <https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#shared-secret>
|
|
||||||
* BOLT 8: <https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#handshake-state>
|
|
||||||
* SECG SEC-1 ECIES: <https://secg.org/sec1-v2.pdf>
|
|
||||||
* Main web site: <https://github.com/ElementsProject/lightning>
|
|
||||||
|
|
||||||
|
|
||||||
[comment]: # ( SHA256STAMP:47c5b466b02b80d40937f40c725733f72c20f3bc26cc7f4dacd5ef858ab0282b)
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true,
|
|
||||||
"required": [
|
|
||||||
"shared_secret"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"shared_secret": {
|
|
||||||
"type": "hex",
|
|
||||||
"description": "the SHA-2 of the compressed encoding of the shared secp256k1 point",
|
|
||||||
"maxLength": 64,
|
|
||||||
"minLength": 64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -128,26 +128,6 @@ struct ext_key *hsm_init(struct lightningd *ld)
|
|||||||
return bip32_base;
|
return bip32_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct command_result *json_getsharedsecret(struct command *cmd,
|
|
||||||
const char *buffer,
|
|
||||||
const jsmntok_t *obj UNNEEDED,
|
|
||||||
const jsmntok_t *params)
|
|
||||||
{
|
|
||||||
struct pubkey *point;
|
|
||||||
struct secret ss;
|
|
||||||
struct json_stream *response;
|
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
|
||||||
p_req("point", ¶m_pubkey, &point),
|
|
||||||
NULL))
|
|
||||||
return command_param_failed();
|
|
||||||
|
|
||||||
ecdh(point, &ss);
|
|
||||||
response = json_stream_success(cmd);
|
|
||||||
json_add_secret(response, "shared_secret", &ss);
|
|
||||||
return command_success(cmd, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct command_result *json_makesecret(struct command *cmd,
|
static struct command_result *json_makesecret(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
@@ -186,12 +166,3 @@ static const struct json_command makesecret_command = {
|
|||||||
"Get a pseudorandom secret key, using some {hex} data."
|
"Get a pseudorandom secret key, using some {hex} data."
|
||||||
};
|
};
|
||||||
AUTODATA(json_command, &makesecret_command);
|
AUTODATA(json_command, &makesecret_command);
|
||||||
|
|
||||||
static const struct json_command getsharedsecret_command = {
|
|
||||||
"getsharedsecret",
|
|
||||||
"utility", /* FIXME: Or "crypto"? */
|
|
||||||
&json_getsharedsecret,
|
|
||||||
"Compute the hash of the Elliptic Curve Diffie Hellman shared secret point from "
|
|
||||||
"this node private key and an input {point}."
|
|
||||||
};
|
|
||||||
AUTODATA(json_command, &getsharedsecret_command);
|
|
||||||
|
|||||||
@@ -2245,32 +2245,6 @@ def test_sendcustommsg(node_factory):
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.developer("needs --dev-force-privkey")
|
|
||||||
def test_getsharedsecret(node_factory):
|
|
||||||
"""
|
|
||||||
Test getsharedsecret command.
|
|
||||||
"""
|
|
||||||
# From BOLT 8 test vectors.
|
|
||||||
options = [
|
|
||||||
{"dev-force-privkey": "1212121212121212121212121212121212121212121212121212121212121212"},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
l1, l2 = node_factory.get_nodes(2, opts=options)
|
|
||||||
|
|
||||||
# Check BOLT 8 test vectors.
|
|
||||||
shared_secret = l1.rpc.getsharedsecret("028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7")['shared_secret']
|
|
||||||
assert (shared_secret == "1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3")
|
|
||||||
|
|
||||||
# Clear the forced privkey of l1.
|
|
||||||
del l1.daemon.opts["dev-force-privkey"]
|
|
||||||
l1.restart()
|
|
||||||
|
|
||||||
# l1 and l2 can generate the same shared secret
|
|
||||||
# knowing only the public key of the other.
|
|
||||||
assert (l1.rpc.getsharedsecret(l2.info["id"])["shared_secret"]
|
|
||||||
== l2.rpc.getsharedsecret(l1.info["id"])["shared_secret"])
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.developer("needs --dev-force-privkey")
|
@pytest.mark.developer("needs --dev-force-privkey")
|
||||||
def test_makesecret(node_factory):
|
def test_makesecret(node_factory):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user