Skip to content

Commit 16fb979

Browse files
authored
Merge pull request #153 from MatthiasGr/est-renewal
Add EST-Based Certificate Renewal
2 parents fd7d66d + d7fe620 commit 16fb979

18 files changed

+335
-8
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ licenseReport {
2626

2727
allprojects {
2828
group = "de.fhg.aisec.ids"
29-
version = "7.2.2"
29+
version = "7.3.0"
3030

3131
val versionRegex = ".*((rc|beta|alpha)-?[0-9]*|-b[0-9.]+)$".toRegex(RegexOption.IGNORE_CASE)
3232

examples/src/main/resources/etc/application.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ logging:
44
de.fhg.aisec.ids.idscp2: trace
55
de.fhg.aisec.ids.camel: trace
66

7+
server:
8+
error:
9+
include-message: always
10+
711
ids-multipart:
812
daps-bean-name: rootDaps
913

47.2 KB
Binary file not shown.

ids-webconsole/src/main/angular/src/app/app.module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ import { UserService } from './users/user.service';
5454
import { UserCardComponent } from './users/user-card.component';
5555
import { NewIdentityESTComponent } from './keycerts/identitynewest.component';
5656
import { ESTService } from './keycerts/est-service';
57+
import { RenewIdentityESTComponent } from './keycerts/identityrenewest.component';
58+
import { SnackbarComponent } from './keycerts/snackbar.component';
5759

5860
@NgModule({ declarations: [
5961
AppComponent,
@@ -88,7 +90,9 @@ import { ESTService } from './keycerts/est-service';
8890
DetailUserComponent,
8991
UserCardComponent,
9092
UsersComponent,
91-
NewIdentityESTComponent
93+
NewIdentityESTComponent,
94+
RenewIdentityESTComponent,
95+
SnackbarComponent
9296
],
9397
bootstrap: [
9498
AppComponent

ids-webconsole/src/main/angular/src/app/app.routing.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { RouteeditorComponent } from './routes/routeeditor/routeeditor.component
1818
import { UsersComponent } from './users/users.component';
1919
import { NewUserComponent } from './users/usernew.component';
2020
import { DetailUserComponent } from './users/userdetail.component';
21+
import { RenewIdentityESTComponent } from './keycerts/identityrenewest.component';
2122
import { RoutesComponent } from './routes/routes.component';
2223
import { NewIdentityESTComponent } from './keycerts/identitynewest.component';
2324

@@ -43,7 +44,8 @@ const appRoutes: Routes = [
4344
{ path: 'usernew', component: NewUserComponent, canActivate: guards },
4445
{ path: 'userdetail', component: DetailUserComponent, canActivate: guards },
4546
{ path: 'certificates', component: KeycertsComponent, canActivate: guards },
46-
{ path: 'identitynewest', component: NewIdentityESTComponent, canActivate: guards }
47+
{ path: 'identitynewest', component: NewIdentityESTComponent, canActivate: guards },
48+
{ path: 'identityrenewest/:alias', component: RenewIdentityESTComponent, canActivate: guards }
4749
]
4850
},
4951
// Pages using the "login" layout (centered full page without sidebar)

ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
{{ certificate.subjectDistinguishedName }}
88
</span>
99
</span>
10-
<span class="mdl-list__item-secondary-content" style="text-align:right">
10+
<div class="mdl-list__item-secondary-content" style="text-align:right;align-items:flex-start;flex-direction:row;">
11+
<a *ngIf="onRenewCallback !== null" class="mdl-list__item-secondary-action mdl-color-text--grey-600" (click)="onRenew(certificate.alias)">
12+
<icon class="material-icons">refresh</icon>
13+
</a>
1114
<a class="mdl-list__item-secondary-action mdl-color-text--grey-600" (click)="onDelete(certificate.alias)">
1215
<icon class="material-icons">delete</icon>
1316
</a>
14-
</span>
17+
</div>
1518
</li>
1619
</ul>

ids-webconsole/src/main/angular/src/app/keycerts/certificate-card.component.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export class CertificateCardComponent implements OnInit {
1616
@Input() public certificates: Certificate[];
1717
@Input() public trusts: Certificate[];
1818
@Input() private readonly onDeleteCallback: (alias: string) => void;
19+
@Input() private readonly onRenewCallback: (alias: string) => void = null;
1920
public result: string;
2021

2122
constructor(private readonly confirmService: ConfirmService) {
@@ -29,6 +30,13 @@ export class CertificateCardComponent implements OnInit {
2930
return item.subjectS + item.subjectCN + item.subjectOU + item.subjectO + item.subjectL + item.subjectC;
3031
}
3132

33+
public onRenew(alias: string): void {
34+
// Sanity check
35+
if (this.onRenewCallback) {
36+
this.onRenewCallback(alias);
37+
}
38+
}
39+
3240
public async onDelete(alias: string): Promise<void> {
3341
return this.confirmService.activate('Are you sure that you want to delete this item?')
3442
.then(res => {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface EstReEnrollment {
2+
estUrl: string;
3+
rootCertHash: string;
4+
alias: string;
5+
};

ids-webconsole/src/main/angular/src/app/keycerts/est-service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Observable } from 'rxjs';
44

55
import { environment } from '../../environments/environment';
66
import { EstEnrollment } from './est-enrollment.interface';
7+
import { EstReEnrollment } from './est-re-enrollment.interface';
78

89
@Injectable()
910
export class ESTService {
@@ -40,4 +41,12 @@ export class ESTService {
4041
responseType: 'text'
4142
});
4243
}
44+
45+
// Renew an existing identity identified by its alias via the EST
46+
public renewIdentity(data: EstReEnrollment) {
47+
return this.http.post(environment.apiURL + '/certs/renew_est_identity', data, {
48+
headers: new HttpHeaders({'Content-Type': 'application/json'}),
49+
responseType: 'text'
50+
});
51+
}
4352
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<div class="mdl-grid">
2+
<div class="mdl-card card-dark mdl-cell mdl-cell--12-col">
3+
<div class="mdl-card__title">
4+
<h2 class="mdl-card__title-text">Renew Identity</h2>
5+
</div>
6+
<div class="mdl-card__supporting-text">
7+
<form (ngSubmit)="onSubmit()" class="mdl-cell--12-col mdl-grid">
8+
<div>
9+
<h5>EST Re-Enrollment</h5>
10+
</div>
11+
<div class="mdl-cell--12-col">
12+
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label has-placeholder mdl-cell--12-col form-group">
13+
<label class="mdl-textfield__label" for="estUrl">EST Url*</label>
14+
<input class="mdl-textfield__input" name="estUrl" type="url" [(ngModel)]="estUrl" required>
15+
</div>
16+
</div>
17+
<div class="mdl-cell--12-col">
18+
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label has-placeholder mdl-cell--12-col form-group">
19+
<label class="mdl-textfield__label" for="rootCertHash">Root CA Certificate Hash*</label>
20+
<input class="mdl-textfield__input" name="rootCertHash" type="text" [(ngModel)]="rootCertHash" required>
21+
</div>
22+
</div>
23+
<div class="mdl-cell--12-col" style="margin-top:20px">
24+
<button type="submit" class="mdl-button mdl-color--accent mdl-button--raised">Renew certificate</button>
25+
</div>
26+
</form>
27+
</div>
28+
</div>
29+
</div>
30+
<snackbar #errorSnackbar subtitle="Check the trusted connector log for more details"/>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Component, ViewChild } from '@angular/core';
2+
import { Title } from '@angular/platform-browser';
3+
import { ESTService } from './est-service';
4+
import { ActivatedRoute, Router } from '@angular/router';
5+
import { HttpErrorResponse } from '@angular/common/http';
6+
import { SnackbarComponent } from './snackbar.component';
7+
8+
@Component({
9+
templateUrl: './identityrenewest.component.html'
10+
})
11+
export class RenewIdentityESTComponent {
12+
estUrl = 'https://daps-dev.aisec.fraunhofer.de';
13+
rootCertHash = '7d3f260abb4b0bfa339c159398c0ab480a251faa385639218198adcad9a3c17d';
14+
15+
@ViewChild("errorSnackbar")
16+
errorSnackbar: SnackbarComponent;
17+
18+
constructor(private readonly titleService: Title,
19+
private readonly estService: ESTService,
20+
private readonly router: Router,
21+
private readonly route: ActivatedRoute) {
22+
this.titleService.setTitle('Renew Identity via the EST');
23+
}
24+
25+
handleError(err: HttpErrorResponse) {
26+
if (err.status === 0) {
27+
this.errorSnackbar.title = 'Network Error';
28+
} else {
29+
const errObj = JSON.parse(err.error);
30+
if (errObj.message) {
31+
this.errorSnackbar.title = errObj.message;
32+
} else {
33+
// Errors have no message if it is disabled by the spring application
34+
this.errorSnackbar.title = `Error response from connector: ${err.status}: ${errObj.error}`;
35+
}
36+
}
37+
this.errorSnackbar.visible = true;
38+
}
39+
40+
onSubmit() {
41+
this.estService.renewIdentity({
42+
estUrl: this.estUrl,
43+
rootCertHash: this.rootCertHash,
44+
alias: this.route.snapshot.paramMap.get('alias')
45+
}).subscribe(
46+
() => this.router.navigate([ '/certificates' ]),
47+
err => this.handleError(err)
48+
);
49+
}
50+
}

ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<h2 class="mdl-card__title-text">My Identities</h2>
66
</div>
77
<div class="mdl-card__supporting-text">
8-
<certificate-card [certificates]="identities" [onDeleteCallback]="deleteIdentity"></certificate-card>
8+
<certificate-card [certificates]="identities" [onDeleteCallback]="deleteIdentity" [onRenewCallback]="renewIdentity"></certificate-card>
99
</div>
1010
<div class="mdl-card__menu">
1111
<button routerLink="/identitynew"

ids-webconsole/src/main/angular/src/app/keycerts/keycerts.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Component } from '@angular/core';
22
import { Title } from '@angular/platform-browser';
3+
import { Router } from '@angular/router';
34

45
import { Certificate } from './certificate';
56
import { CertificateService } from './keycert.service';
@@ -13,7 +14,9 @@ export class KeycertsComponent {
1314
public identities: Certificate[];
1415
public certificates: Certificate[];
1516

16-
constructor(private readonly titleService: Title, private readonly certificateService: CertificateService) {
17+
constructor(private readonly titleService: Title,
18+
private readonly certificateService: CertificateService,
19+
private readonly rotuer: Router) {
1720
this.titleService.setTitle('Certificates');
1821

1922
this.certificateService.getIdentities()
@@ -44,4 +47,8 @@ export class KeycertsComponent {
4447
}
4548
});
4649
};
50+
51+
public renewIdentity = (alias: string) => {
52+
this.rotuer.navigate(['/identityrenewest', alias]);
53+
};
4754
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.snackbar {
2+
-webkit-transform: translate(-50%, 100px);
3+
transform: translate(-50%, 100px);
4+
}
5+
6+
.snackbar-content {
7+
display: flex;
8+
flex-direction: column;
9+
}
10+
11+
.snackbar-subtitle {
12+
font-size: smaller;
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<div id="est-error-snackbar" class="mdl-snackbar" [ngClass]="{'snackbar': !visible, 'mdl-snackbar--active': visible}">
2+
<div class="mdl-snackbar__text snackbar-content">
3+
<span>{{ title }}</span>
4+
<span *ngIf="subtitle !== null" class="mdl-color-text--grey-300 snackbar-subtitle">
5+
{{ subtitle }}
6+
</span>
7+
</div>
8+
<button class="mdl-snackbar__action" type="button" (click)="invokeOnDismiss()">Dismiss</button>
9+
</div>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Component, Input } from '@angular/core';
2+
3+
@Component({
4+
selector: 'snackbar',
5+
templateUrl: './snackbar.component.html',
6+
styleUrl: './snackbar.component.css'
7+
})
8+
export class SnackbarComponent {
9+
@Input() title: string = null;
10+
@Input() subtitle: string = null;
11+
@Input() visible: boolean = false;
12+
@Input() onDismiss: ()=>void = null;
13+
14+
invokeOnDismiss() {
15+
if (this.onDismiss !== null) {
16+
this.onDismiss()
17+
} else {
18+
this.visible = false;
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)