Skip to content

Commit 610515c

Browse files
committed
chore: adding dev API endpoint to test client certificates
1 parent db55991 commit 610515c

16 files changed

+415
-14
lines changed

dev-api/api-es.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import express from 'express';
22
import session from 'express-session';
3+
import fs from 'fs';
4+
import path from 'path';
5+
import http from 'http';
6+
import https from 'https';
37
import apiRouter from './routes.js';
4-
58
/* eslint-disable no-console */
69

710
const app = express();
@@ -21,17 +24,25 @@ const sessionConfig = {
2124
app.use(session(sessionConfig));
2225
app.use('/v1', apiRouter);
2326

24-
const portStr = process.argv.slice(2).find((arg) => arg.indexOf('--PORT') === 0);
25-
let port;
26-
if (!isNaN(portStr)) {
27-
port = Number(portStr);
28-
} else {
29-
port = 8080;
30-
}
27+
const findOpt = (name) => process.argv.slice(2).find((arg) => arg.indexOf(`--${name}`) === 0);
28+
const findPortValue = (name, defaultValue) => {
29+
const str = findOpt(name);
30+
if (isNaN(str)) {
31+
return defaultValue;
32+
}
33+
return Number(str);
34+
};
35+
36+
const port = findPortValue('PORT', 3080);
37+
const portSsl = findPortValue('SSLPORT', 3443);
38+
3139

3240
// Basic 404 handler
3341
app.use((req, res) => {
34-
res.status(404).send('Not Found');
42+
res.status(404).send({
43+
error: true,
44+
message: `Route ${req.url} not found`
45+
});
3546
});
3647

3748
// Basic error handler
@@ -43,7 +54,17 @@ app.use((err, req, res) => {
4354
});
4455
});
4556

46-
const server = app.listen(port, () => {
47-
const port = server.address().port;
48-
console.info(`App listening on port ${port}`);
57+
const options = {
58+
key: fs.readFileSync(path.join(__dirname, 'cc', 'server_key.pem')),
59+
cert: fs.readFileSync(path.join(__dirname, 'cc', 'server_cert.pem')),
60+
requestCert: true,
61+
rejectUnauthorized: false,
62+
ca: [fs.readFileSync(path.join(__dirname, 'cc', 'server_cert.pem'))],
63+
};
64+
65+
http.createServer(app).listen(port, () => {
66+
console.info(`HTTP listening on port ${port}`);
67+
});
68+
https.createServer(options, app).listen(portSsl, () => {
69+
console.info(`HTTPS listening on port ${portSsl}`);
4970
});

dev-api/auth-basic.route.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { BaseApi } from './base-api.js';
44
const router = express.Router();
55
export default router;
66

7-
class AuthBaiscRoute extends BaseApi {
7+
class AuthBasicRoute extends BaseApi {
88
sendUnauthorized(res) {
99
res.status(401);
1010
res.set('WWW-Authenticate', 'Basic realm="This resource is protected"');
@@ -35,7 +35,7 @@ class AuthBaiscRoute extends BaseApi {
3535
}
3636
}
3737

38-
const api = new AuthBaiscRoute();
38+
const api = new AuthBasicRoute();
3939
api.setCors(router);
4040
api.wrapApi(router, [
4141
['/:username/:password', 'requireAuthorized'],

dev-api/auth-cc.route.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import express from 'express';
2+
import { BaseApi } from './base-api.js';
3+
4+
const router = express.Router();
5+
export default router;
6+
7+
class AuthCcRoute extends BaseApi {
8+
sendUnauthorized(res) {
9+
res.status(401);
10+
res.set('WWW-Authenticate', 'Basic realm="This resource is protected"');
11+
res.send('Auth required');
12+
}
13+
14+
requireAuthorized(req, res) {
15+
if (typeof req.socket.getPeerCertificate !== 'function') {
16+
this.sendError(res, 'SSL connection is required.');
17+
return;
18+
}
19+
const cert = req.socket.getPeerCertificate();
20+
let status;
21+
let message;
22+
if (req.client.authorized) {
23+
status = 200;
24+
message = {
25+
authenticated: true,
26+
name: cert.subject.CN,
27+
issuer: cert.issuer.CN,
28+
};
29+
} else if (cert.subject) {
30+
status = 403;
31+
message = {
32+
authenticated: false,
33+
name: cert.subject.CN,
34+
issuer: cert.issuer.CN,
35+
};
36+
} else {
37+
status = 401;
38+
message = {
39+
authenticated: false,
40+
name: 'Unknown',
41+
issuer: 'Unknown',
42+
};
43+
}
44+
res.writeHead(status, {
45+
'Content-Type': 'application/json; charset=UTF-8',
46+
});
47+
res.end(JSON.stringify(message));
48+
}
49+
}
50+
51+
const api = new AuthCcRoute();
52+
api.setCors(router);
53+
api.wrapApi(router, [
54+
['/', 'requireAuthorized'],
55+
]);

dev-api/cc/bob.p12

3.85 KB
Binary file not shown.

dev-api/cc/bob_cert.pem

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEmDCCAoACCQDQPRzVnOSbujANBgkqhkiG9w0BAQUFADAOMQwwCgYDVQQDDANC
3+
b2IwHhcNMjAwMTMwMjIxNDE4WhcNMzAwMTI3MjIxNDE4WjAOMQwwCgYDVQQDDANC
4+
b2IwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDhVwZJi8R2LfQhvP7q
5+
TXNl76Y8aaMagBpgYoVwOhkIcZYlsr5Yq5tkUSOh9VB+TXNwG44mjpv3bUZHGTJ9
6+
R2aB5rFj/m+bkVWDwnl1eStbXEoKx4va004KWML9vAO76RxlhZu64tWfSgROrB5K
7+
jCKMuNwUUNPJOOAoQB91i0SE3LunDVKN6U01PPkyIAy4X63ImWDrQzXd8D9NN1Qq
8+
9ZmM4ovMqTwndZV1YkY3ZiZf4HFmGZzq8LwkpgObYqGLUeFXM0nueNulSs6TzN/o
9+
bmV7LiZ8sWsRHozzeaVfNIlAg4V1A5RY/K0H+HT2ySqRVUbHpns6aVbmRk+v646y
10+
95zJKIeeeWB4zjyD6wp2l8bO4GZe4knF9UFlHHrCDHrjIlzvtHpZlHXPOIo/y7zs
11+
AJLzmwduHFbid2rzQj5ObqSH5QrEvhvx2i2PAgHGhPWVyu+ESNFa5RnXYTkYN0OS
12+
cBCnr3qaiHHUnZZECwU/m+b7djyqmfFGmHTj/a7M6E500xlhFR9X468FXU/6cIn1
13+
9kIxkbHf4QsOaviH79Axxw5fQvx8PCx+qMQahhCk+vrDYZzCrCPyJhE2vkKPdEIH
14+
4YhvGyiwc1cR1XPCjeuQsQMhjRa2kBlz20TEUnhcZPQ2/5TX+rSy0IpeuG2ZknnH
15+
ruP8viYHWn2dPK2cZVjXITpeQQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQAytQcL
16+
BcZvujS18/0s1p6mhlhdpSCqMmeFie8aFTvWsdPiC4RCgtEefGuKqg6VRkSPxTSW
17+
nkBZ3haSkYBhSUqhGGYUgmftLBb10QUb3FEX4FDZipj8g3qkZ/JBMMDtJaqVpMqN
18+
mFjkFgVW41nJmeVd1J+XLn+BygfW9cdlBF1E0QlgS1W0apKwzR57jw5rRJnasAdZ
19+
hWA/4K9sMkGThvakDFOcSMiUGsJyiNy9kXHnreqOSUzGbyYiryKWv8Mc9oGSysyH
20+
eA37/cVJKrzou2Tpq42AGQZVZFkc+kcYf4WbX5VnyAUUyZzkwZDFvHSOdt7d2quh
21+
zEnxJjPSms1DxMOVFCeJD2rcFnAtt2iDXjJT47x1zsN6rI2GAgSfS0G1vWIuc/A1
22+
FgbQQwS+AgD1YJmRIw41gq0rcVMtwZ4xZEGPRrvypuKcudY6aWvEnANHQfPnWfCC
23+
acPnPZ3mstzIsdCXKboRmppUQCFfVcst/JxPQO0luPRncujds5pEJhQBsw0WXApJ
24+
ITNg/cK/HSCg2uKGp1Z5OBkyiH8t0QEpLoB11KxSXaCJRbKquDabFTNvkTHZ8/Q6
25+
5NOhx9ioIPhRtwe5Hppq+BDZQk4dLE5Z++iehCDCzBhc7vUWH+T8LLWa3UrrI/9z
26+
QAmhJhQOHauxMLW2iW4GdWZ/AvK2ZiZKcAKkKA==
27+
-----END CERTIFICATE-----

dev-api/cc/bob_csr.pem

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIEUzCCAjsCAQAwDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOC
3+
Ag8AMIICCgKCAgEA4VcGSYvEdi30Ibz+6k1zZe+mPGmjGoAaYGKFcDoZCHGWJbK+
4+
WKubZFEjofVQfk1zcBuOJo6b921GRxkyfUdmgeaxY/5vm5FVg8J5dXkrW1xKCseL
5+
2tNOCljC/bwDu+kcZYWbuuLVn0oETqweSowijLjcFFDTyTjgKEAfdYtEhNy7pw1S
6+
jelNNTz5MiAMuF+tyJlg60M13fA/TTdUKvWZjOKLzKk8J3WVdWJGN2YmX+BxZhmc
7+
6vC8JKYDm2Khi1HhVzNJ7njbpUrOk8zf6G5ley4mfLFrER6M83mlXzSJQIOFdQOU
8+
WPytB/h09skqkVVGx6Z7OmlW5kZPr+uOsvecySiHnnlgeM48g+sKdpfGzuBmXuJJ
9+
xfVBZRx6wgx64yJc77R6WZR1zziKP8u87ACS85sHbhxW4ndq80I+Tm6kh+UKxL4b
10+
8dotjwIBxoT1lcrvhEjRWuUZ12E5GDdDknAQp696mohx1J2WRAsFP5vm+3Y8qpnx
11+
Rph04/2uzOhOdNMZYRUfV+OvBV1P+nCJ9fZCMZGx3+ELDmr4h+/QMccOX0L8fDws
12+
fqjEGoYQpPr6w2Gcwqwj8iYRNr5Cj3RCB+GIbxsosHNXEdVzwo3rkLEDIY0WtpAZ
13+
c9tExFJ4XGT0Nv+U1/q0stCKXrhtmZJ5x67j/L4mB1p9nTytnGVY1yE6XkECAwEA
14+
AaAAMA0GCSqGSIb3DQEBCwUAA4ICAQCQunBCVTlO7OaQmO+Nv8rRuKHDRJwEx7dv
15+
UC+YKViW85fo3+/vE6OKUEnc2Z2ol3pRSQxTVLlQO/SxLEB/bCa8+ghd11clHH3X
16+
n3aBD31eTBF9TUBBp6ng72NQDHno5KrQd0aW/rDbejy7RGqK2uKimvf9MhqXCcUk
17+
WUCTe2LM4tpkn2rxC27WaIVTUNYFrqNxXoII/rcWXxlYDHdUsxYC1iNy/9YNeKut
18+
mHYH7AzEI7PKEYGdlOhOSCT/HmeJ+4Kdy6ZPbSELdTZAy2QJcwT1VU2bap7WsDPC
19+
QlJnSkJo6B+lSd4LnwMFKSuTWKKhw27QJlRPDsjqlyHsbigK6SftzdToBjnYMSET
20+
RRIHyc1Caqo6CQrPRzD6qzFXgTyi/hLiMml2/ArQj7vtkP5Rj4ZUt63bD1lySUiu
21+
AfySW8amy6UU224Htir4lHX76R/uB2bdh8g1z2lo8dS0Mzn8a64CH/8xKWFnc6ey
22+
qBOI5sucInOYjUZpIIs4UxrRz9LQhuARMSGO4GOF3WeqsHbxU3qnWDA5Bt6epbnb
23+
BxGg9GS8XLT+rDFKY1ZZ0l3EzPQKClTc5OGYROvRYbZDpx/kI/66InNn/me+IGnC
24+
02P+/dxblgnTDj+T0X6scGqvptw6ze2u58t4q/LjN2lCGvNsqWY44dVAAnBC0MRc
25+
E7GjggNetA==
26+
-----END CERTIFICATE REQUEST-----

dev-api/cc/bob_key.pem

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
51+
YUx6IfWP4P+GB5wLp93d5Ul1MjADJ6E+
52+
-----END PRIVATE KEY-----

dev-api/cc/cert-instructions.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Note, all certificates are valid for 10 years so I don't have to redo this every now and then
2+
3+
# Server self signed certificate for demo purposes
4+
echo "Generating server certificate..."
5+
openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem -nodes -days 3650 -subj "/CN=localhost/O=Client\ Certificate\ Demo"
6+
7+
# Client certificates
8+
9+
# Pawel has a valid certificate
10+
echo "Generating certificate for Pawel"
11+
openssl req -newkey rsa:4096 -keyout pawel_key.pem -out pawel_csr.pem -nodes -days 3650 -subj "/CN=Pawel"
12+
13+
# Bob has self signed certificate
14+
echo "Generating certificate for Bob"
15+
openssl req -newkey rsa:4096 -keyout bob_key.pem -out bob_csr.pem -nodes -days 3650 -subj "/CN=Bob"
16+
17+
# Pawel's CSR is signed with server key
18+
echo "Signing Pawel's certificate with server's key"
19+
openssl x509 -req -in pawel_csr.pem -CA server_cert.pem -CAkey server_key.pem -out pawel_cert.pem -set_serial 01 -days 3650
20+
21+
# Bob signs his own certificate
22+
echo "Signing Bob's certificate with Bob's key"
23+
openssl x509 -req -in bob_csr.pem -signkey bob_key.pem -out bob_cert.pem -days 3650
24+
25+
# Create P12 format certificate that can be importend in a web browser or in ARC, obviously
26+
echo "Creating Pawel's P12 certificate"
27+
openssl pkcs12 -export -clcerts -in pawel_cert.pem -inkey pawel_key.pem -out pawel.p12
28+
echo "Creating Bob's P12 certificate"
29+
openssl pkcs12 -export -in bob_cert.pem -inkey bob_key.pem -out bob.p12

dev-api/cc/password.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
All certs are protected by a password:
2+
secret

dev-api/cc/pawel.p12

3.88 KB
Binary file not shown.

0 commit comments

Comments
 (0)