Skip to content

Commit 20d77d0

Browse files
authored
support - cert duration, source addresses and extensions (#26)
more granual control over cert duration and support for source addresses, extensions
1 parent e7e2232 commit 20d77d0

File tree

10 files changed

+1200
-975
lines changed

10 files changed

+1200
-975
lines changed

server/ssh-key-signer-server/package-lock.json

Lines changed: 938 additions & 857 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/ssh-key-signer-server/package.json

Lines changed: 71 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"type": "module",
55
"dependencies": {
66
"@polymer/polymer": "3.5.2",
7-
"@vaadin/bundles": "24.9.0",
7+
"@vaadin/bundles": "24.9.2",
88
"@vaadin/common-frontend": "0.0.19",
99
"@vaadin/hilla-file-router": "24.9.2",
1010
"@vaadin/hilla-frontend": "24.9.2",
@@ -14,12 +14,12 @@
1414
"@vaadin/hilla-react-form": "24.9.2",
1515
"@vaadin/hilla-react-i18n": "24.9.2",
1616
"@vaadin/hilla-react-signals": "24.9.2",
17-
"@vaadin/polymer-legacy-adapter": "24.9.0",
18-
"@vaadin/react-components": "24.9.0",
17+
"@vaadin/polymer-legacy-adapter": "24.9.2",
18+
"@vaadin/react-components": "24.9.2",
1919
"@vaadin/vaadin-development-mode-detector": "2.0.7",
20-
"@vaadin/vaadin-lumo-styles": "24.9.0",
21-
"@vaadin/vaadin-material-styles": "24.9.0",
22-
"@vaadin/vaadin-themable-mixin": "24.9.0",
20+
"@vaadin/vaadin-lumo-styles": "24.9.2",
21+
"@vaadin/vaadin-material-styles": "24.9.2",
22+
"@vaadin/vaadin-themable-mixin": "24.9.2",
2323
"@vaadin/vaadin-usage-statistics": "2.1.3",
2424
"construct-style-sheets-polyfill": "3.1.0",
2525
"date-fns": "2.29.3",
@@ -47,7 +47,6 @@
4747
"@vaadin/hilla-generator-plugin-transfertypes": "24.9.2",
4848
"@vaadin/hilla-generator-utils": "24.9.2",
4949
"@vitejs/plugin-react": "4.7.0",
50-
"async": "3.2.6",
5150
"glob": "11.0.3",
5251
"magic-string": "0.30.19",
5352
"rollup-plugin-brotli": "3.1.0",
@@ -64,7 +63,7 @@
6463
"vaadin": {
6564
"dependencies": {
6665
"@polymer/polymer": "3.5.2",
67-
"@vaadin/bundles": "24.9.0",
66+
"@vaadin/bundles": "24.9.2",
6867
"@vaadin/common-frontend": "0.0.19",
6968
"@vaadin/hilla-file-router": "24.9.2",
7069
"@vaadin/hilla-frontend": "24.9.2",
@@ -74,12 +73,12 @@
7473
"@vaadin/hilla-react-form": "24.9.2",
7574
"@vaadin/hilla-react-i18n": "24.9.2",
7675
"@vaadin/hilla-react-signals": "24.9.2",
77-
"@vaadin/polymer-legacy-adapter": "24.9.0",
78-
"@vaadin/react-components": "24.9.0",
76+
"@vaadin/polymer-legacy-adapter": "24.9.2",
77+
"@vaadin/react-components": "24.9.2",
7978
"@vaadin/vaadin-development-mode-detector": "2.0.7",
80-
"@vaadin/vaadin-lumo-styles": "24.9.0",
81-
"@vaadin/vaadin-material-styles": "24.9.0",
82-
"@vaadin/vaadin-themable-mixin": "24.9.0",
79+
"@vaadin/vaadin-lumo-styles": "24.9.2",
80+
"@vaadin/vaadin-material-styles": "24.9.2",
81+
"@vaadin/vaadin-themable-mixin": "24.9.2",
8382
"@vaadin/vaadin-usage-statistics": "2.1.3",
8483
"construct-style-sheets-polyfill": "3.1.0",
8584
"date-fns": "2.29.3",
@@ -107,7 +106,6 @@
107106
"@vaadin/hilla-generator-plugin-transfertypes": "24.9.2",
108107
"@vaadin/hilla-generator-utils": "24.9.2",
109108
"@vitejs/plugin-react": "4.7.0",
110-
"async": "3.2.6",
111109
"glob": "11.0.3",
112110
"magic-string": "0.30.19",
113111
"rollup-plugin-brotli": "3.1.0",
@@ -121,7 +119,7 @@
121119
"workbox-core": "7.3.0",
122120
"workbox-precaching": "7.3.0"
123121
},
124-
"hash": "a3cae0d1a5c5998fe407d8f4833e4087f379ff7dd06a230238b25e6ed1a41829"
122+
"hash": "3d1a09d0d44b884d5c60ef5afc8fe390658bc0b8b448896cb1cfd3619b8d294b"
125123
},
126124
"overrides": {
127125
"@vaadin/bundles": "$@vaadin/bundles",
@@ -148,64 +146,64 @@
148146
"@vaadin/vaadin-themable-mixin": "$@vaadin/vaadin-themable-mixin",
149147
"@vaadin/vaadin-lumo-styles": "$@vaadin/vaadin-lumo-styles",
150148
"@vaadin/vaadin-material-styles": "$@vaadin/vaadin-material-styles",
151-
"@vaadin/a11y-base": "24.9.0",
152-
"@vaadin/accordion": "24.9.0",
153-
"@vaadin/app-layout": "24.9.0",
154-
"@vaadin/avatar": "24.9.0",
155-
"@vaadin/avatar-group": "24.9.0",
156-
"@vaadin/button": "24.9.0",
157-
"@vaadin/card": "24.9.0",
158-
"@vaadin/checkbox": "24.9.0",
159-
"@vaadin/checkbox-group": "24.9.0",
160-
"@vaadin/combo-box": "24.9.0",
161-
"@vaadin/component-base": "24.9.0",
162-
"@vaadin/confirm-dialog": "24.9.0",
163-
"@vaadin/context-menu": "24.9.0",
164-
"@vaadin/custom-field": "24.9.0",
165-
"@vaadin/date-picker": "24.9.0",
166-
"@vaadin/date-time-picker": "24.9.0",
167-
"@vaadin/details": "24.9.0",
168-
"@vaadin/dialog": "24.9.0",
169-
"@vaadin/email-field": "24.9.0",
170-
"@vaadin/field-base": "24.9.0",
171-
"@vaadin/field-highlighter": "24.9.0",
172-
"@vaadin/form-layout": "24.9.0",
173-
"@vaadin/grid": "24.9.0",
174-
"@vaadin/horizontal-layout": "24.9.0",
175-
"@vaadin/icon": "24.9.0",
176-
"@vaadin/icons": "24.9.0",
177-
"@vaadin/input-container": "24.9.0",
178-
"@vaadin/integer-field": "24.9.0",
179-
"@vaadin/item": "24.9.0",
180-
"@vaadin/list-box": "24.9.0",
181-
"@vaadin/lit-renderer": "24.9.0",
182-
"@vaadin/login": "24.9.0",
183-
"@vaadin/markdown": "24.9.0",
184-
"@vaadin/master-detail-layout": "24.9.0",
185-
"@vaadin/menu-bar": "24.9.0",
186-
"@vaadin/message-input": "24.9.0",
187-
"@vaadin/message-list": "24.9.0",
188-
"@vaadin/multi-select-combo-box": "24.9.0",
189-
"@vaadin/notification": "24.9.0",
190-
"@vaadin/number-field": "24.9.0",
191-
"@vaadin/overlay": "24.9.0",
192-
"@vaadin/password-field": "24.9.0",
193-
"@vaadin/popover": "24.9.0",
194-
"@vaadin/progress-bar": "24.9.0",
195-
"@vaadin/radio-group": "24.9.0",
196-
"@vaadin/scroller": "24.9.0",
197-
"@vaadin/select": "24.9.0",
198-
"@vaadin/side-nav": "24.9.0",
199-
"@vaadin/split-layout": "24.9.0",
200-
"@vaadin/tabs": "24.9.0",
201-
"@vaadin/tabsheet": "24.9.0",
202-
"@vaadin/text-area": "24.9.0",
203-
"@vaadin/text-field": "24.9.0",
204-
"@vaadin/time-picker": "24.9.0",
205-
"@vaadin/tooltip": "24.9.0",
206-
"@vaadin/upload": "24.9.0",
149+
"@vaadin/a11y-base": "24.9.2",
150+
"@vaadin/accordion": "24.9.2",
151+
"@vaadin/app-layout": "24.9.2",
152+
"@vaadin/avatar": "24.9.2",
153+
"@vaadin/avatar-group": "24.9.2",
154+
"@vaadin/button": "24.9.2",
155+
"@vaadin/card": "24.9.2",
156+
"@vaadin/checkbox": "24.9.2",
157+
"@vaadin/checkbox-group": "24.9.2",
158+
"@vaadin/combo-box": "24.9.2",
159+
"@vaadin/component-base": "24.9.2",
160+
"@vaadin/confirm-dialog": "24.9.2",
161+
"@vaadin/context-menu": "24.9.2",
162+
"@vaadin/custom-field": "24.9.2",
163+
"@vaadin/date-picker": "24.9.2",
164+
"@vaadin/date-time-picker": "24.9.2",
165+
"@vaadin/details": "24.9.2",
166+
"@vaadin/dialog": "24.9.2",
167+
"@vaadin/email-field": "24.9.2",
168+
"@vaadin/field-base": "24.9.2",
169+
"@vaadin/field-highlighter": "24.9.2",
170+
"@vaadin/form-layout": "24.9.2",
171+
"@vaadin/grid": "24.9.2",
172+
"@vaadin/horizontal-layout": "24.9.2",
173+
"@vaadin/icon": "24.9.2",
174+
"@vaadin/icons": "24.9.2",
175+
"@vaadin/input-container": "24.9.2",
176+
"@vaadin/integer-field": "24.9.2",
177+
"@vaadin/item": "24.9.2",
178+
"@vaadin/list-box": "24.9.2",
179+
"@vaadin/lit-renderer": "24.9.2",
180+
"@vaadin/login": "24.9.2",
181+
"@vaadin/markdown": "24.9.2",
182+
"@vaadin/master-detail-layout": "24.9.2",
183+
"@vaadin/menu-bar": "24.9.2",
184+
"@vaadin/message-input": "24.9.2",
185+
"@vaadin/message-list": "24.9.2",
186+
"@vaadin/multi-select-combo-box": "24.9.2",
187+
"@vaadin/notification": "24.9.2",
188+
"@vaadin/number-field": "24.9.2",
189+
"@vaadin/overlay": "24.9.2",
190+
"@vaadin/password-field": "24.9.2",
191+
"@vaadin/popover": "24.9.2",
192+
"@vaadin/progress-bar": "24.9.2",
193+
"@vaadin/radio-group": "24.9.2",
194+
"@vaadin/scroller": "24.9.2",
195+
"@vaadin/select": "24.9.2",
196+
"@vaadin/side-nav": "24.9.2",
197+
"@vaadin/split-layout": "24.9.2",
198+
"@vaadin/tabs": "24.9.2",
199+
"@vaadin/tabsheet": "24.9.2",
200+
"@vaadin/text-area": "24.9.2",
201+
"@vaadin/text-field": "24.9.2",
202+
"@vaadin/time-picker": "24.9.2",
203+
"@vaadin/tooltip": "24.9.2",
204+
"@vaadin/upload": "24.9.2",
207205
"@vaadin/router": "2.0.0",
208-
"@vaadin/vertical-layout": "24.9.0",
209-
"@vaadin/virtual-list": "24.9.0"
206+
"@vaadin/vertical-layout": "24.9.2",
207+
"@vaadin/virtual-list": "24.9.2"
210208
}
211209
}
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
package io.binarycodes.homelab.sshkeysigner.config;
22

3+
import jakarta.validation.constraints.NotBlank;
34
import org.springframework.boot.context.properties.ConfigurationProperties;
45

6+
import java.time.Duration;
7+
import java.util.List;
8+
59
@ConfigurationProperties(prefix = "app")
610
public record ApplicationProperties(
11+
@NotBlank
712
String caUserPath,
13+
@NotBlank
814
String caHostPath,
9-
Integer caUserValidity,
10-
Integer caHostValidity
15+
Duration caUserValidity,
16+
Duration caHostValidity,
17+
List<String> sourceAddresses,
18+
List<String> knownExtensions
1119
) {
1220
}

server/ssh-key-signer-server/src/main/java/io/binarycodes/homelab/sshkeysigner/keymanagement/KeyController.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.binarycodes.homelab.sshkeysigner.keymanagement;
22

3-
import java.nio.charset.StandardCharsets;
4-
53
import io.binarycodes.homelab.lib.SignPublicKeyRequest;
64
import io.binarycodes.homelab.lib.SignedPublicKeyDownload;
75
import lombok.extern.log4j.Log4j2;
@@ -36,38 +34,40 @@ public KeyInfo generateKey(@RequestParam final String comment, @RequestParam fin
3634
public ResponseEntity<SignedPublicKeyDownload> signUserKey(final JwtAuthenticationToken principal, @RequestBody final SignPublicKeyRequest signPublicKeyRequest) {
3735
final var validationOk = validateAuthentication(principal, signPublicKeyRequest);
3836
if (!validationOk) {
39-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
40-
.build();
37+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
4138
}
4239

43-
final var signed = keyService.signUserKey(signPublicKeyRequest.filename(), signPublicKeyRequest.publicKey()
44-
.getBytes(StandardCharsets.UTF_8), signPublicKeyRequest.principal());
40+
final var signed = keyService.signUserKey(
41+
signPublicKeyRequest.filename(),
42+
signPublicKeyRequest.publicKey(),
43+
principal.getToken().getId(),
44+
signPublicKeyRequest.principal()
45+
);
4546

4647
return signed.map(signedPublicKeyDownload -> {
47-
return ResponseEntity.ok()
48-
.body(signedPublicKeyDownload);
48+
return ResponseEntity.ok().body(signedPublicKeyDownload);
4949
})
50-
.orElseGet(() -> ResponseEntity.badRequest()
51-
.build());
50+
.orElseGet(() -> ResponseEntity.badRequest().build());
5251
}
5352

5453
@PostMapping("/hostSign")
5554
public ResponseEntity<SignedPublicKeyDownload> signHostKey(final JwtAuthenticationToken principal, @RequestBody final SignPublicKeyRequest signPublicKeyRequest) {
5655
final var validationOk = validateAuthentication(principal, signPublicKeyRequest);
5756
if (!validationOk) {
58-
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
59-
.build();
57+
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
6058
}
6159

62-
final var signed = keyService.signHostKey(signPublicKeyRequest.filename(), signPublicKeyRequest.publicKey()
63-
.getBytes(StandardCharsets.UTF_8), signPublicKeyRequest.principal());
60+
final var signed = keyService.signHostKey(
61+
signPublicKeyRequest.filename(),
62+
signPublicKeyRequest.publicKey(),
63+
principal.getToken().getId(),
64+
signPublicKeyRequest.principal()
65+
);
6466

6567
return signed.map(signedPublicKeyDownload -> {
66-
return ResponseEntity.ok()
67-
.body(signedPublicKeyDownload);
68+
return ResponseEntity.ok().body(signedPublicKeyDownload);
6869
})
69-
.orElseGet(() -> ResponseEntity.badRequest()
70-
.build());
70+
.orElseGet(() -> ResponseEntity.badRequest().build());
7171
}
7272

7373
private boolean validateAuthentication(final JwtAuthenticationToken principal, final SignPublicKeyRequest signPublicKeyRequest) {
@@ -81,8 +81,7 @@ private boolean validateAuthentication(final JwtAuthenticationToken principal, f
8181
return false;
8282
}
8383

84-
if (!principal.getName()
85-
.equals(signPublicKeyRequest.principal())) {
84+
if (!principal.getName().equals(signPublicKeyRequest.principal())) {
8685
log.fatal("Invalid principal - \"{}\". Request and authorization do not match. Refusing to sign certificate for \"{}\".",
8786
principal.getName(), signPublicKeyRequest.principal());
8887

0 commit comments

Comments
 (0)