Skip to content

Enable TLS Configuration with in-memory PEM strings #2

Closed
@CMCDragonkai

Description

@CMCDragonkai

Specification

In QUIC our current system requires passing a file path into QUICConfig.

{
  certChainFromPemFile: string | undefined;
  privKeyFromPemFile: string | undefined;
}

These 2 properties are required on the server side, while they are optional on the client side. PK will of course use these 2 on both client and server.

These 2 properties are later used by config.buildQuicheConfig:

  if (config.certChainFromPemFile != null) {
    quicheConfig.loadCertChainFromPemFile(config.certChainFromPemFile);
  }
  if (config.privKeyFromPemFile != null) {
    quicheConfig.loadPrivKeyFromPemFile(config.privKeyFromPemFile);
  }

It's better to be able to pass PEM strings, then require the QUIC client and QUIC server to read certificates and keys from the local filesystem. It's more secure as we don't leave any secrets on the local filesystem.

In order to do this, we need to add a new factory method to the config.rs.

#[napi(factory)]
pub fn with_boring_ssl_ctx(version: i64, certPEM: String, keyPEM: String) -> Result<Self> {
  // ... figure out this ...
}

The body of this function will need to take the PEM strings bridged by napi-rs, and then use the boring package to turn them into the x509 objects.

Subsequently use boring::ssl::SslContext::builder to create a SSL context builder, which then takes those objects and builds the SSL context.

Finally it should be possible to use quiche::Config::with_boring_ssl_ctx to finally build a config object with string cert and key.

Currently in PK, we have the types:

CertificatePEMChain
PrivateKeyPEM

Both are string types. These will be used when we want to load certs and key into the QUIC connection.

Tests should test the usage of this on both client and server, with the verifyPeer option set to true.

Tests should ensure that certificate chains are also accepted. The cert chain PEM doesn't just mean 1 certificate, it could have a whole chain of certificates.

An additional problem is dealing with certificate and key rotation. I'll address this in a separate issue.

Additional context

Tasks

  1. Bring in the boring package into Cargo.toml.
  2. Update the shell.nix with rustPlatform.bindgenHook so that boring can actually compile
  3. Update the config.rs with the with_boring_ssl_ctx method. Use chat gpt and github copilot to help you find out what kind of code to write.
  4. Compile it with npm run napi-build.
  5. Expose the method in src/native/types.ts
  6. Change the buildQuicheConfig to take the TLS cert pem and key pem strings.
  7. Eliminate the file path options, we won't even bother implementing these.
  8. Change tests to stop using the localhost.key and localhost.crt, but instead synthetically generate these 2 in-memory now. You can use peculiar's x509 library as a devDependency and follow the PK's src/keys/utils/x509.ts to understand how to generate a relevant certificate chain for testing purposes.
  9. You can sanity check by reading the localhost.crt and localhost.key first as strings. But it's better we can use fastcheck to generate different kinds of certs for testing.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions