Skip to content

Commit

Permalink
feat: Support Private CA for server certificates. (#408)
Browse files Browse the repository at this point in the history
Support TLS validation on instances configured with a customer-managed private CA. Includes integration test.
  • Loading branch information
hessjcg authored Jan 10, 2025
1 parent 25f5ccd commit 36f1304
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 17 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ jobs:
POSTGRES_DB:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_DB
POSTGRES_CAS_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_CAS_CONNECTION_NAME
POSTGRES_CAS_PASS:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_CAS_PASS
POSTGRES_CUSTOMER_CAS_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_CUSTOMER_CAS_CONNECTION_NAME
POSTGRES_CUSTOMER_CAS_PASS:${{ vars.GOOGLE_CLOUD_PROJECT }}/POSTGRES_CUSTOMER_CAS_PASS
SQLSERVER_CONNECTION_NAME:${{ vars.GOOGLE_CLOUD_PROJECT }}/SQLSERVER_CONNECTION_NAME
SQLSERVER_USER:${{ vars.GOOGLE_CLOUD_PROJECT }}/SQLSERVER_USER
SQLSERVER_PASS:${{ vars.GOOGLE_CLOUD_PROJECT }}/SQLSERVER_PASS
Expand Down Expand Up @@ -188,6 +190,8 @@ jobs:
POSTGRES_DB: "${{ steps.secrets.outputs.POSTGRES_DB }}"
POSTGRES_CAS_CONNECTION_NAME: "${{ steps.secrets.outputs.POSTGRES_CAS_CONNECTION_NAME }}"
POSTGRES_CAS_PASS: "${{ steps.secrets.outputs.POSTGRES_CAS_PASS }}"
POSTGRES_CUSTOMER_CAS_CONNECTION_NAME: "${{ steps.secrets.outputs.POSTGRES_CUSTOMER_CAS_CONNECTION_NAME }}"
POSTGRES_CUSTOMER_CAS_PASS: "${{ steps.secrets.outputs.POSTGRES_CUSTOMER_CAS_PASS }}"
SQLSERVER_CONNECTION_NAME: "${{ steps.secrets.outputs.SQLSERVER_CONNECTION_NAME }}"
SQLSERVER_USER: "${{ steps.secrets.outputs.SQLSERVER_USER }}"
SQLSERVER_PASS: "${{ steps.secrets.outputs.SQLSERVER_PASS }}"
Expand Down
2 changes: 0 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 18 additions & 15 deletions src/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,26 @@ export function validateCertificate(
dnsName: string
) {
return (hostname: string, cert: tls.PeerCertificate): Error | undefined => {
if (serverCaMode === 'GOOGLE_MANAGED_CAS_CA') {
if (!serverCaMode || serverCaMode === 'GOOGLE_MANAGED_INTERNAL_CA') {
// Legacy CA Mode
if (!cert || !cert.subject) {
return new CloudSQLConnectorError({
message: 'No certificate to verify',
code: 'ENOSQLADMINVERIFYCERT',
});
}
const expectedCN = `${instanceInfo.projectId}:${instanceInfo.instanceId}`;
if (cert.subject.CN !== expectedCN) {
return new CloudSQLConnectorError({
message: `Certificate had CN ${cert.subject.CN}, expected ${expectedCN}`,
code: 'EBADSQLADMINVERIFYCERT',
});
}
return undefined;
} else {
// Standard TLS Verify Full hostname verification using SAN
return tls.checkServerIdentity(dnsName, cert);
}
if (!cert || !cert.subject) {
return new CloudSQLConnectorError({
message: 'No certificate to verify',
code: 'ENOSQLADMINVERIFYCERT',
});
}
const expectedCN = `${instanceInfo.projectId}:${instanceInfo.instanceId}`;
if (cert.subject.CN !== expectedCN) {
return new CloudSQLConnectorError({
message: `Certificate had CN ${cert.subject.CN}, expected ${expectedCN}`,
code: 'EBADSQLADMINVERIFYCERT',
});
}
return undefined;
};
}

Expand Down
26 changes: 26 additions & 0 deletions system-test/pg-connect.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,29 @@ t.test(
connector.close();
}
);

t.test(
'open connection to Customer Private CAS-based CA instance and retrieves standard pg tables',
async t => {
const connector = new Connector();
const clientOpts = await connector.getOptions({
instanceConnectionName: String(
process.env.POSTGRES_CUSTOMER_CAS_CONNECTION_NAME
),
});
const client = new Client({
...clientOpts,
user: String(process.env.POSTGRES_USER),
password: String(process.env.POSTGRES_CUSTOMER_CAS_PASS),
database: String(process.env.POSTGRES_DB),
});
client.connect();
const {
rows: [result],
} = await client.query('SELECT NOW();');
const returnedDate = result['now'];
t.ok(returnedDate.getTime(), 'should have valid returned date object');
await client.end();
connector.close();
}
);
26 changes: 26 additions & 0 deletions system-test/pg-connect.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,29 @@ t.test(
connector.close();
}
);

t.test(
'open connection to Customer Private CAS-based CA instance and retrieves standard pg tables',
async t => {
const connector = new Connector();
const clientOpts = await connector.getOptions({
instanceConnectionName: String(
process.env.POSTGRES_CUSTOMER_CAS_CONNECTION_NAME
),
});
const client = new Client({
...clientOpts,
user: String(process.env.POSTGRES_USER),
password: String(process.env.POSTGRES_CUSTOMER_CAS_PASS),
database: String(process.env.POSTGRES_DB),
});
client.connect();
const {
rows: [result],
} = await client.query('SELECT NOW();');
const returnedDate = result['now'];
t.ok(returnedDate.getTime(), 'should have valid returned date object');
await client.end();
connector.close();
}
);
26 changes: 26 additions & 0 deletions system-test/pg-connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,29 @@ t.test(
connector.close();
}
);

t.test(
'open connection to Customer Private CAS-based CA instance and retrieves standard pg tables',
async t => {
const connector = new Connector();
const clientOpts = await connector.getOptions({
instanceConnectionName: String(
process.env.POSTGRES_CUSTOMER_CAS_CONNECTION_NAME
),
});
const client = new Client({
...clientOpts,
user: String(process.env.POSTGRES_USER),
password: String(process.env.POSTGRES_CUSTOMER_CAS_PASS),
database: String(process.env.POSTGRES_DB),
});
client.connect();
const {
rows: [result],
} = await client.query('SELECT NOW();');
const returnedDate = result['now'];
t.ok(returnedDate.getTime(), 'should have valid returned date object');
await client.end();
connector.close();
}
);

0 comments on commit 36f1304

Please sign in to comment.