Skip to content

Conversation

@jtobin
Copy link
Member

@jtobin jtobin commented Aug 30, 2025

Adds certificate verification for TLS communication with price oracles, mostly following the suggestions proposed in #1278. Adds configuration options for skipping certificate verification, distrusting the operating system's root CA list, and using a custom certificate.

Resolves #1278.

@jtobin jtobin added security mainnet preparedness Goal issues to be completed before mainnet release RFQ Work relating to TAP channel Request For Quote (RFQ). oracle labels Aug 30, 2025
@coveralls
Copy link

coveralls commented Aug 30, 2025

Pull Request Test Coverage Report for Build 20063273326

Details

  • 78 of 90 (86.67%) changed or added relevant lines in 5 files are covered.
  • 66 unchanged lines in 17 files lost coverage.
  • Overall coverage increased (+0.01%) to 56.773%

Changes Missing Coverage Covered Lines Changed/Added Lines %
rfq/tls.go 26 28 92.86%
tapcfg/server.go 3 6 50.0%
tapcfg/config.go 26 33 78.79%
Files with Coverage Reduction New Missed Lines %
commitment/tap.go 1 85.65%
fn/context_guard.go 1 91.94%
asset/group_key.go 2 72.15%
tapdb/addrs.go 2 76.56%
tapdb/universe.go 2 81.27%
tapgarden/custodian.go 2 76.83%
universe_rpc_diff.go 2 76.0%
universe/syncer.go 2 85.93%
proof/verifier.go 3 85.57%
tapgarden/planter.go 3 80.26%
Totals Coverage Status
Change from base Build 20053123061: 0.01%
Covered Lines: 65407
Relevant Lines: 115207

💛 - Coveralls

@jtobin jtobin force-pushed the oracle-tls branch 2 times, most recently from 77cad42 to 9910220 Compare August 31, 2025 13:27
@jtobin jtobin requested review from GeorgeTsagk and ffranr August 31, 2025 19:59
@jtobin jtobin marked this pull request as ready for review August 31, 2025 20:00
@jtobin
Copy link
Member Author

jtobin commented Aug 31, 2025

(Changed this from draft; I think the litd tests are failing for an unrelated reason.)

@jtobin
Copy link
Member Author

jtobin commented Sep 3, 2025

(As pointed out by @ZZiigguurraatt, to be more precise: TLS support already existed for price oracles, but certificate verification was skipped entirely.)

@levmi levmi moved this from 🆕 New to 🏗 In progress in Taproot-Assets Project Board Sep 4, 2025
@levmi levmi moved this from 🏗 In progress to 👀 In review in Taproot-Assets Project Board Sep 4, 2025
Copy link
Contributor

@ffranr ffranr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other cases where we need more precise control over TLS behavior. For example:

// serverDialOpts returns the set of server options needed to connect to the
// server using a TLS connection.
func serverDialOpts() ([]grpc.DialOption, error) {
var opts []grpc.DialOption
// Skip TLS certificate verification.
tlsConfig := tls.Config{InsecureSkipVerify: true}
transportCredentials := credentials.NewTLS(&tlsConfig)
opts = append(opts, grpc.WithTransportCredentials(transportCredentials))
return opts, nil
}

With that in mind, I wonder if we could define a more general, reusable solution in something like the new rfq/tls.go file, especially given the need for configuration and the importance of which package owns this logic.

Comment on lines 116 to 135
name: "invalid custom certificate",
expectInsecure: false,
tlsConfig: &TLSConfig{
Enabled: true,
InsecureSkipVerify: false,
TrustSystemRootCAs: false,
CustomCertificates: []byte(invalidCertificate),
},
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I see the purpose of invalidCertificate here. It doesn't look like the test actually exercises its invalidity.

More broadly, do we need certificate examples in our unit tests at all? It seems like we're testing the behavior of the underlying TLS/certificate library rather than the logic we're adding on top of it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these tests are super important, but they perform a decent sanity check of the configureTransportCredentials function -- basically, that it uses the supplied config to interact with the underlying libraries in the way that I expect. The tests are cheap, so why not, sort of.

I debated deleting the invalid certificate case, but wound up deciding to return an error in configureTransportCredentials when no valid custom certificates could be found anyway, so now the invalid certificate case exercises the invalidity of the certificate. 😄

@jtobin jtobin added this to the v0.8 milestone Sep 29, 2025
@jtobin jtobin changed the base branch from main to 0-8-0-staging October 21, 2025 11:24
@jtobin jtobin changed the base branch from 0-8-0-staging to main December 8, 2025 12:34
Introduces rfq/tls.go, which contains a basic TLSConfig type and default
value of such. The default value, which for now only indicates that
certificate verification should be skipped, is used in place of the
'dialInsecure' bool when setting up the price oracle RPC.
Adds both 'TrustSystemRootCAs' and 'CustomCertificates' to the rfq
TLSConfig. The former indicates whether or not to trust the operating
system's root CA list; the latter allows additional certificates (CA or
self-signed) to be trusted.

Also adds a basic unit test skeleton.
We don't skip certificate verification by default, and also default to
trusting the operating system's root CA list.
Adds some basic test cases for configuring transport credentials.
Previously we would ignore this, but it's arguably better to return an
error here that at least describes what happened.
Ensures that certificate verification is skipped when constructing a
communication channel with the itest oracle harness.
Ensures the price oracle TLS toggle fits the existing pattern of flags
defaulting to false.
@jtobin
Copy link
Member Author

jtobin commented Dec 9, 2025

With that in mind, I wonder if we could define a more general, reusable solution in something like the new rfq/tls.go file, especially given the need for configuration and the importance of which package owns this logic.

I looked into this and agree that it's probably worth centralizing our TLS handling, but I'd consider it out of scope for this change set, which does resolve a concrete issue as-is. Maybe we can open a broader "refactor TLS handling" issue for that?

I get the following hits for "crypto/tls" imports, as a rough metric:

$ ack -l "crypto/tls" --ignore-dir=itest --ignore-dir=docs
cmd/commands/conn.go
proof/courier.go
internal/test/grpc.go
universe_rpc_registrar.go
tapcfg/config.go
rfq/tls.go
authmailbox/client.go
universe/proof_download_test.go

@jtobin jtobin changed the title rfq: add tls support for price oracles rfq: add price oracle certificate verification Dec 10, 2025
jtobin added a commit to jtobin/lightning-terminal that referenced this pull request Dec 10, 2025
The mock oracle uses a self-signed certificate for TLS, but we're not
concerned with having tapd verify it in the itest environment. This
commit adds the 'experimental.rfq.priceoracletlsinsecure' flag added in
lightninglabs/taproot-assets#1775 to the litd args list, instructing
tapd not to verify certificates.
@jtobin
Copy link
Member Author

jtobin commented Dec 10, 2025

The LiT itest failure should be resolved by lightninglabs/lightning-terminal#1190.

@jtobin jtobin requested a review from ffranr December 10, 2025 08:30
@lightninglabs-deploy
Copy link

@ffranr: review reminder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mainnet preparedness Goal issues to be completed before mainnet release oracle RFQ Work relating to TAP channel Request For Quote (RFQ). security

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

[bug]: price oracle TLS/SSL certificate validation missing

4 participants