Skip to content

Commit

Permalink
fix: ed25519 certs now work, this includes the fast check generated…
Browse files Browse the repository at this point in the history
… ones

I've also updated the tests to use a random selection of the example cert fixtures and the generated polykey cert.

* Fixes #8

[ci skip]
  • Loading branch information
tegefaulkes authored and CMCDragonkai committed May 17, 2023
1 parent ed919ca commit 2346e8c
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 76 deletions.
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export function retry(scid: Uint8Array, dcid: Uint8Array, newScid: Uint8Array, t
export function versionIsSupported(version: number): boolean
export class Config {
constructor()
static withBoringSslCtx(certPem?: Uint8Array | undefined | null, keyPem?: Uint8Array | undefined | null): Config
static withBoringSslCtx(certPem?: Uint8Array | undefined | null, keyPem?: Uint8Array | undefined | null, supportedKeyAlgos?: string | undefined | null): Config
loadCertChainFromPemFile(file: string): void
loadPrivKeyFromPemFile(file: string): void
loadVerifyLocationsFromFile(file: string): void
Expand Down
25 changes: 18 additions & 7 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { Config as QuicheConfig } from './native/types';
import { quiche } from './native';

// All the algos chrome supports + ed25519
const supportedPrivateKeyAlgosDefault =
"ed25519:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512";

export type TlsConfig = {
certChainPem: string | null;
privKeyPem: string | null;
Expand All @@ -11,6 +15,7 @@ export type TlsConfig = {

type QUICConfig = {
tlsConfig: TlsConfig | undefined;
supportedPrivateKeyAlgos: string | undefined;
verifyPeer: boolean;
logKeys: string | undefined;
grease: boolean;
Expand All @@ -29,6 +34,7 @@ type QUICConfig = {

const clientDefault: QUICConfig = {
tlsConfig: undefined,
supportedPrivateKeyAlgos: supportedPrivateKeyAlgosDefault,
logKeys: undefined,
verifyPeer: false,
grease: true,
Expand All @@ -53,6 +59,7 @@ const clientDefault: QUICConfig = {

const serverDefault: QUICConfig = {
tlsConfig: undefined,
supportedPrivateKeyAlgos: supportedPrivateKeyAlgosDefault,
logKeys: undefined,
verifyPeer: false,
grease: true,
Expand All @@ -76,14 +83,18 @@ const serverDefault: QUICConfig = {
};

function buildQuicheConfig(config: QUICConfig): QuicheConfig {
let quicheConfig: QuicheConfig;
let certChainPem: Buffer | null = null;
let privKeyPem: Buffer | null = null;
if (config.tlsConfig != null && 'certChainPem' in config.tlsConfig) {
quicheConfig = quiche.Config.withBoringSslCtx(
config.tlsConfig.certChainPem != null ? Buffer.from(config.tlsConfig.certChainPem) : null,
config.tlsConfig.privKeyPem != null ? Buffer.from(config.tlsConfig.privKeyPem) : null,
)
} else {
quicheConfig = new quiche.Config();
if (config.tlsConfig.certChainPem != null) certChainPem = Buffer.from(config.tlsConfig.certChainPem)
if (config.tlsConfig.privKeyPem != null) privKeyPem = Buffer.from(config.tlsConfig.privKeyPem)
}
let quicheConfig: QuicheConfig = quiche.Config.withBoringSslCtx(
certChainPem,
privKeyPem,
config.supportedPrivateKeyAlgos ?? null,
);
if (config.tlsConfig != null && 'certChainFromPemFile' in config.tlsConfig) {
if (config.tlsConfig?.certChainFromPemFile != null) {
quicheConfig.loadCertChainFromPemFile(config.tlsConfig.certChainFromPemFile);
}
Expand Down
11 changes: 8 additions & 3 deletions src/native/napi/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,13 @@ impl Config {
pub fn with_boring_ssl_ctx(
cert_pem: Option<Uint8Array>,
key_pem: Option<Uint8Array>,
supported_key_algos: Option<String>,
) -> Result<Self> {
let mut ssl_ctx_builder = boring::ssl::SslContextBuilder::new(
boring::ssl::SslMethod::tls(),
).or_else(
|err| Err(Error::from_reason(err.to_string()))
)?;
// ssl_ctx_builder.set_verify(
// boring::ssl::SslVerifyMode::NONE
// );
// Processing and adding the cert chain
if let Some(cert_pem) = cert_pem {
let x509_cert_chain = boring::x509::X509::stack_from_pem(
Expand Down Expand Up @@ -93,6 +91,13 @@ impl Config {
|err| Err(Error::from_reason(err.to_string()))
)?;
}
// Adding supported private key algorithms
if let Some(supported_key_algos) = supported_key_algos {
ssl_ctx_builder.set_sigalgs_list(&supported_key_algos)
.or_else(
|err| Err(Error::from_reason(err.to_string()))
)?;
}
let ssl_ctx= ssl_ctx_builder.build();
let config = quiche::Config::with_boring_ssl_ctx(
quiche::PROTOCOL_VERSION,
Expand Down
5 changes: 3 additions & 2 deletions src/native/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ interface Config {
interface ConfigConstructor {
new(): Config;
withBoringSslCtx(
cert_pem: Uint8Array | null,
key_pem: Uint8Array | null,
certPem: Uint8Array | null,
keyPem: Uint8Array | null,
supportedKeyAlgos: String | null,
): Config;
};

Expand Down
68 changes: 5 additions & 63 deletions tests/QUICClient.test.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,19 @@
import type { Crypto, Host, Hostname, Port } from '@/types';
import { webcrypto } from 'crypto';
import type { Crypto, Host, Port } from '@/types';
import Logger, { LogLevel, StreamHandler, formatting } from '@matrixai/logger';
import QUICClient from '@/QUICClient';
import QUICServer from '@/QUICServer';
import QUICConnection from '@/QUICConnection';
import * as events from '@/events';
import * as utils from '@/utils';
import * as testsUtils from './utils';
import * as tls from 'tls';
import * as errors from '@/errors';
import { fc } from '@fast-check/jest';
import * as tlsUtils from './tlsUtils';
import * as certFixtures from './fixtures/certFixtures';


const privKeyPem = `
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAovJl4noV+8myMOOhG+/1kpsAvmGaiz3o3+gnAINpFiUvANWU
LUhoyyeQAzCom2yOl6WEH1574Hz6jsnwB3BFDj1wcBtbjMlwYpqfkJYsRQGIrOGD
VGI3PSpcBWGOdfPnREAQrp5cL1TKRSuFtyjZR2lZY4DxUAr6JEmC2aOObv7gcr1W
nhdO9PnY9aXhF2aVXsThkp8izP2ET9C7OmpMdajnVVbTW4PFU5YLnKFZFY5CmnaR
08QWFByxGVKDkt5c3sPvBnI0Dfc1LvfCKFJZ4CtJs7+i+O2Y2ticLwur678wvXO9
OGN6CIIC2A9c4H8I8qpE+N/frYfTg/E7/j0dbQIDAQABAoIBAB99SpU21LLA6q+p
/cOBXurDC6S/Bfessik7GvZtbsx5yRiXLbiGisHf1mPXbm4Cz5ecw+iwAK6EWINp
oPo/BwlWdDkmAE43y4Eysm1lqA552mjWd+PByz0Fx5y+mqJOzT2SR+cG8XewIhq1
63RW745uXHjvPTMju+1xS1k101u9lL0VCo5cfPpS12fLYiVtR721CayWydfABuc9
Xbj38G6lw5QGipjS+r7t588dKa9APMffKZPB3q0g65TZrOd0hjvZMQMvPe5aY3SP
UpLD3GhmO/0Khsl31WkZSDPkogPBq6BqvJZa/qrSQHIh9pUX6FFOTCw3ANWQutMH
681LRsECgYEAz5pLp5BrMfg/ToPMaLKcpYiY//UhI+ZjUJ8aL51D8Jl4DOAUN1ge
tpBKDRm0ayLOdFeok9S8CQItrAvkFyHBiRK6R1CgyXqSCdBRPsqdN74+K0DsEloU
nNdXejGGijSSezBcvNYVlJC+7yKLgpC2wK36oLFEPHdNJPIC3wZBtFECgYEAyO8L
/6KfVOaUJCc02vUAU8Ap6bVA5xlXD4sxI5w6FCwcHCzlAoHGsjA2aWsnxi43z41p
pRR9IySUEPZxmh76Tzs9+Dthshkjrrx8CuTIky37BIzFDioqH2Ncj5+DCAly3IU4
NjCMQOp+Yx5u9UZfkdcJj31+JUCBn1BdW22Z3F0CgYB9ftdW/t1eAqQ6UUAC1l4N
Tuq2Z7dV3VKSDOumdtn4Gr3QgrCV2CYQ1F5/VteSoCLPf6H/Y20bwP5c7389YIF+
3BxROfNIeFjJp+1FGPQ7Gzy3pvJOEbg+K4rM6h1bdHZME6sr1/qJqYpSQr60+cgP
59wGwcHvD2tJ9yY3LbAQUQKBgDefZPTpMa4w/kVbzRfnxqVohrG5iTPwIdedsoan
ErTO2SE7lFGzVyuwiP95uFL2LGD6Rop6N4Ho+EwRzLTbanNQdQEofwzsRKJ0buod
FyEXE2vZBBu9tFdoDBF+GKm6498DyeHGYqz9vOr3W8PuLTqUCoN8O9VYHAncF1vd
5T/JAoGAeWb5iqhDhkrZDSi5GreFh2zVlDanZJqQn4UpUhotO4gtKDzMqM/rxV95
RZ7zsFD22yY06cXePpMOfw4qAUDZuwoZgVH5MLW3IWJPkg++nG6GfTBaHmYmXK/M
uPSJlPjTsCL+dUX+7VbrfntypnVALhtX3bZo3rsQQmUci/NjDhU=
-----END RSA PRIVATE KEY-----
`

const certChainPem = `
-----BEGIN CERTIFICATE-----
MIIDJjCCAg6gAwIBAgIRAImdTwINUpu7qX/uYWmVT44wDQYJKoZIhvcNAQELBQAw
FDESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTIzMDQxMDA1MDk1OVoXDTI0MDQwOTA1
MDk1OVowFDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAovJl4noV+8myMOOhG+/1kpsAvmGaiz3o3+gnAINpFiUvANWU
LUhoyyeQAzCom2yOl6WEH1574Hz6jsnwB3BFDj1wcBtbjMlwYpqfkJYsRQGIrOGD
VGI3PSpcBWGOdfPnREAQrp5cL1TKRSuFtyjZR2lZY4DxUAr6JEmC2aOObv7gcr1W
nhdO9PnY9aXhF2aVXsThkp8izP2ET9C7OmpMdajnVVbTW4PFU5YLnKFZFY5CmnaR
08QWFByxGVKDkt5c3sPvBnI0Dfc1LvfCKFJZ4CtJs7+i+O2Y2ticLwur678wvXO9
OGN6CIIC2A9c4H8I8qpE+N/frYfTg/E7/j0dbQIDAQABo3MwcTAOBgNVHQ8BAf8E
BAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBR0
zbkYQmSgopJsbuNKOQV9qjYu7TAhBgNVHREEGjAYhwR/AAABhxAAAAAAAAAAAAAA
AAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBAQAWLolrv0NuKqhZndYLPCT3C013Qo6y
QeQPbyZbJgHhRZd2feP8sEQ1U4f48OKL5ejWEKOaUvH/sVI9Jume4ve2xOxqz+ST
csZqUqinnUT/12jwGOys2IIEPBnlMxBFon54G336+LGgl9CX+rXKeJZgIbmZpcCa
J948KRJwJ4E4UgnNIY/e4J5nCpScA0b5GlmcvpoV5yBoIf6vvnrWeyyl4rotPx9Q
jm/r7v5BQrwMjbcrLCA9Nob5tSMEHDjlvt4cNzOnMWdsjB735QaMsA8qZX8m2NpX
jti9iwz2QT6q1s+PjS/gbflIO3j4FP4XOEQGtWm9iqPbVhoUIB9PBED3
-----END CERTIFICATE-----
`

const tlsArb = fc.constant(certFixtures.tlsConfigFileRSA1);
// const tlsArb = tlsUtils.tlsConfigArb(tlsUtils.keyPairsArb(1));
// const tlsArb = fc.constant({
// certChainPem,
// privKeyPem,
// });
const tlsArb = fc.oneof(
certFixtures.tlsConfigExampleArb,
tlsUtils.tlsConfigArb(),
);
describe(QUICClient.name, () => {
const logger = new Logger(`${QUICClient.name} Test`, LogLevel.DEBUG, [
new StreamHandler(formatting.format`${formatting.level}:${formatting.keys}:${formatting.msg}`),
Expand Down
32 changes: 32 additions & 0 deletions tests/fixtures/certFixtures.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from 'fs';
import path from 'path';
import { fc } from '@fast-check/jest';

function fixturePath(name: string) {
return {
Expand Down Expand Up @@ -71,6 +72,33 @@ const tlsConfigMemECDSA2 = {
privKeyPem: fs.readFileSync(tlsConfigFileECDSA2.privKeyFromPemFile).toString(),
};

const tlsConfigRSAExampleArb = fc.oneof(
fc.constant(tlsConfigFileRSA1),
fc.constant(tlsConfigFileRSA2),
fc.constant(tlsConfigMemRSA1),
fc.constant(tlsConfigMemRSA2),
)

const tlsConfigECDSAExampleArb = fc.oneof(
fc.constant(tlsConfigFileECDSA1),
fc.constant(tlsConfigFileECDSA2),
fc.constant(tlsConfigMemECDSA1),
fc.constant(tlsConfigMemECDSA2),
)

const tlsConfigOKPExampleArb = fc.oneof(
fc.constant(tlsConfigFileOKP1),
fc.constant(tlsConfigFileOKP2),
fc.constant(tlsConfigMemOKP1),
fc.constant(tlsConfigMemOKP2),
)

const tlsConfigExampleArb = fc.oneof(
tlsConfigRSAExampleArb,
tlsConfigECDSAExampleArb,
tlsConfigOKPExampleArb,
)


export {
tlsConfigFileRSA1,
Expand All @@ -85,4 +113,8 @@ export {
tlsConfigMemOKP2,
tlsConfigMemECDSA1,
tlsConfigMemECDSA2,
tlsConfigRSAExampleArb,
tlsConfigECDSAExampleArb,
tlsConfigOKPExampleArb,
tlsConfigExampleArb,
}

0 comments on commit 2346e8c

Please sign in to comment.