An mTLS client certificate should only be usable with its node We create two instances, each generates its own certs and keys, and then we try to cross the wires.
(node_factory)
| 175 | |
| 176 | |
| 177 | def test_grpc_wrong_auth(node_factory): |
| 178 | """An mTLS client certificate should only be usable with its node |
| 179 | |
| 180 | We create two instances, each generates its own certs and keys, |
| 181 | and then we try to cross the wires. |
| 182 | """ |
| 183 | # These only exist if we have rust! |
| 184 | |
| 185 | grpc_port = reserve() |
| 186 | l1, l2 = node_factory.get_nodes(2, opts={ |
| 187 | "start": False, |
| 188 | "grpc-port": str(grpc_port), |
| 189 | }) |
| 190 | l1.start() |
| 191 | wait_for_grpc_start(l1) |
| 192 | |
| 193 | def connect(node): |
| 194 | p = Path(node.daemon.lightning_dir) / TEST_NETWORK |
| 195 | cert, key, ca = [f.open('rb').read() for f in [ |
| 196 | p / 'client.pem', |
| 197 | p / 'client-key.pem', |
| 198 | p / "ca.pem"]] |
| 199 | |
| 200 | creds = grpc.ssl_channel_credentials( |
| 201 | root_certificates=ca, |
| 202 | private_key=key, |
| 203 | certificate_chain=cert, |
| 204 | ) |
| 205 | |
| 206 | channel = grpc.secure_channel( |
| 207 | f"localhost:{grpc_port}", |
| 208 | creds, |
| 209 | options=(('grpc.ssl_target_name_override', 'cln'),) |
| 210 | ) |
| 211 | return nodegrpc.NodeStub(channel) |
| 212 | |
| 213 | stub = connect(l1) |
| 214 | # This should work, it's the correct node |
| 215 | stub.Getinfo(nodepb.GetinfoRequest()) |
| 216 | |
| 217 | l1.stop() |
| 218 | l2.start() |
| 219 | wait_for_grpc_start(l2) |
| 220 | |
| 221 | # This should not work, it's a different node |
| 222 | with pytest.raises(Exception, match=r'Socket closed|StatusCode.UNAVAILABLE'): |
| 223 | stub.Getinfo(nodepb.GetinfoRequest()) |
| 224 | |
| 225 | # Now load the correct ones and we should be good to go |
| 226 | stub = connect(l2) |
| 227 | stub.Getinfo(nodepb.GetinfoRequest()) |