SSL Cert Fixes

This commit is contained in:
2026-09-07 09:43:36 +10:00
parent 5afccaffa8
commit fc2898083c
6 changed files with 96 additions and 1 deletions
+18
View File
@@ -1224,6 +1224,24 @@ router.get('/tls/ca.crt', (req, res) => {
res.send(ca);
});
/**
* The same authority in DER form, for Jamf Pro and anything else built on Apple's
* tooling. Offered as .cer and .der because different consoles insist on
* different extensions for the identical bytes.
*/
router.get(['/tls/ca.cer', '/tls/ca.der'], (req, res) => {
try {
const der = tls.caCertificateDer();
if (!der) return res.status(404).send('No certificate authority has been generated yet.');
const ext = req.path.endsWith('.der') ? 'der' : 'cer';
res.setHeader('Content-Type', 'application/pkix-cert');
res.setHeader('Content-Disposition', `attachment; filename="visitor-signin-ca.${ext}"`);
res.send(der);
} catch (err) {
res.status(500).send(`Could not convert the certificate: ${err.message}`);
}
});
router.post('/tls/renew', requireOwner, (req, res) => {
try {
// A brand new CA means every kiosk device has to trust it again, so it is
+19
View File
@@ -121,6 +121,25 @@ function startRedirectServer() {
http
.createServer((req, res) => {
// DER for Apple tooling, PEM for everything else.
if (req.url === '/ca.cer' || req.url === '/ca.der') {
try {
const der = tls.caCertificateDer();
if (!der) {
res.writeHead(404, { 'Content-Type': 'text/plain' });
return res.end('No certificate authority has been generated yet.');
}
res.writeHead(200, {
'Content-Type': 'application/pkix-cert',
'Content-Disposition': 'attachment; filename="visitor-signin-ca.cer"',
});
return res.end(der);
} catch (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
return res.end(`Could not convert the certificate: ${err.message}`);
}
}
if (req.url === '/ca.crt' || req.url === '/ca.pem') {
const ca = tls.caCertificate();
if (!ca) {
+13
View File
@@ -225,6 +225,19 @@ export function describe() {
};
}
/**
* The CA in DER form.
*
* The .crt on disk is PEM: base64 text between BEGIN/END lines. Apple's tooling,
* and therefore Jamf Pro's certificate payload, wants the raw binary DER instead
* and rejects the file on its extension. Same certificate, different wrapper.
*/
export function caCertificateDer() {
const p = paths();
if (!fs.existsSync(p.caCert)) return null;
return openssl(['x509', '-in', p.caCert, '-outform', 'der']);
}
export function caCertificate() {
const p = paths();
return fs.existsSync(p.caCert) ? fs.readFileSync(p.caCert) : null;