├── Tools ├── sbom-public-ui │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── favicon.ico │ │ ├── app │ │ │ ├── sbom-input │ │ │ │ ├── sbom-input.component.spec.ts │ │ │ │ ├── sbom-input.model.ts │ │ │ │ └── sbom-input.component.css │ │ │ ├── footer │ │ │ │ ├── footer.component.html │ │ │ │ ├── footer.component.spec.ts │ │ │ │ ├── footer.component.ts │ │ │ │ └── footer.component.css │ │ │ ├── app.component.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.html │ │ │ ├── header │ │ │ │ ├── header.component.spec.ts │ │ │ │ ├── header.component.html │ │ │ │ ├── header.component.ts │ │ │ │ └── header.component.css │ │ │ ├── app.component.css │ │ │ ├── app.module.ts │ │ │ ├── services │ │ │ │ ├── health-check.service.ts │ │ │ │ └── rest-endpoints.service.ts │ │ │ ├── app.component.spec.ts │ │ │ ├── styles │ │ │ │ └── global.scss │ │ │ └── models │ │ │ │ └── spdx.model.ts │ │ ├── main.ts │ │ └── index.html │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── .editorconfig │ ├── Dockerfile │ ├── .gitignore │ ├── tsconfig.json │ ├── README.md │ ├── package.json │ └── angular.json └── sbom-public-service │ ├── .settings │ ├── org.springframework.ide.eclipse.prefs │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs │ ├── images │ └── media │ │ └── image2.png │ ├── src │ └── main │ │ ├── resources │ │ ├── application.yml │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── sepia │ │ └── sbomutils │ │ ├── model │ │ ├── AuthTokenModel.java │ │ ├── AuthModel.java │ │ ├── CycloneDXHashModel.java │ │ ├── CycloneDXPropertyModel.java │ │ ├── ErrorModel.java │ │ ├── CycloneDXLicenseChoiceModel.java │ │ ├── SpdxStartEndPointerModel.java │ │ ├── CycloneDXOrganizationalContactModel.java │ │ ├── SpdxSnippetsRangesModel.java │ │ ├── DefaultWebResponse.java │ │ ├── SpdxPackageVerificationCodeModel.java │ │ ├── CycloneDXOrganizationalEntityModel.java │ │ ├── ChangeLog.java │ │ ├── CycloneDXToolModel.java │ │ ├── DataWebResponse.java │ │ ├── BomStatusDisplayModel.java │ │ ├── CycloneDXExternalReferenceModel.java │ │ ├── SpdxReviewedsModel.java │ │ ├── BomFileDetailsModel.java │ │ ├── BomStatusModel.java │ │ ├── CycloneDXMetaDataModel.java │ │ ├── ComponentStatusModel.java │ │ ├── CycloneDXLicenseModel.java │ │ ├── SpdxSnippetModel.java │ │ ├── SpdxCreationInfoModel.java │ │ ├── SBOMInputModel.java │ │ ├── SpdxPackageExternalRefsModel.java │ │ ├── CycloneDXInputModel.java │ │ ├── SpdxExternalDocumentRefModel.java │ │ ├── SpdxAnnotationModel.java │ │ ├── SpdxFilesModel.java │ │ ├── SpdxInputModel.java │ │ ├── SpdxCrossRefModel.java │ │ ├── SpdxPackageInfoModel.java │ │ ├── SpdxHasExtractedLicensingInfoModel.java │ │ ├── CycloneDXComponentModel.java │ │ ├── SpdxRelationshipModel.java │ │ ├── BomFilesInputModel.java │ │ └── SpdxPackageChecksumsModel.java │ │ ├── SbomUtilsServiceApplication.java │ │ ├── exception │ │ ├── CycloneConversionException.java │ │ └── InvalidFileNameException.java │ │ ├── CorsFilter.java │ │ ├── util │ │ ├── CustomMultipartFile.java │ │ ├── JsonPathFinder.java │ │ ├── Constants.java │ │ └── SbomFileUtils.java │ │ ├── SbomUtilsServiceAppConfig.java │ │ └── service │ │ └── SbomUtilityService.java │ ├── Dockerfile │ ├── .project │ ├── README.md │ ├── .classpath │ ├── pom.xml │ ├── mvnw.cmd │ └── mvnw ├── Images ├── image-2.png ├── image-3.png ├── Dashboard.png └── SEPIA-workflow.png ├── Presentations └── 20240912_BFOSS24 │ ├── bfoss24-Praes-Kern-SEPIA-SBOM-Exchange-Procedures-Interfaces-and-Architecture.odp │ ├── bfoss24-Praes-Kern-SEPIA-SBOM-Exchange-Procedures-Interfaces-and-Architecture.pdf │ ├── README.md │ └── README_de.md ├── docker-compose.yml ├── .github └── workflows │ └── reuse.yml ├── CONTRIBUTORS ├── LICENSES ├── MIT.txt ├── LicenseRef-scancode-dco-1.1.txt ├── CC0-1.0.txt └── Apache-2.0.txt ├── Schema ├── SPDX │ └── Bosch_SEPIA │ │ └── bosch_sepia_spdx_2.3.md └── CycloneDX │ └── Bosch_SEPIA │ └── bosch_sepia_cyclonedx_1.4.md ├── DCO.txt ├── REUSE.toml ├── Installation.md └── README.md /Tools/sbom-public-ui/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Images/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Images/image-2.png -------------------------------------------------------------------------------- /Images/image-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Images/image-3.png -------------------------------------------------------------------------------- /Images/Dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Images/Dashboard.png -------------------------------------------------------------------------------- /Images/SEPIA-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Images/SEPIA-workflow.png -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Tools/sbom-public-ui/src/favicon.ico -------------------------------------------------------------------------------- /Tools/sbom-public-service/.settings/org.springframework.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | boot.validation.initialized=true 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/images/media/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Tools/sbom-public-service/images/media/image2.png -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/sbom-input/sbom-input.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ -------------------------------------------------------------------------------- /Tools/sbom-public-service/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 4 | 8 | -------------------------------------------------------------------------------- /Presentations/20240912_BFOSS24/bfoss24-Praes-Kern-SEPIA-SBOM-Exchange-Procedures-Interfaces-and-Architecture.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Presentations/20240912_BFOSS24/bfoss24-Praes-Kern-SEPIA-SBOM-Exchange-Procedures-Interfaces-and-Architecture.odp -------------------------------------------------------------------------------- /Presentations/20240912_BFOSS24/bfoss24-Praes-Kern-SEPIA-SBOM-Exchange-Procedures-Interfaces-and-Architecture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChain-Project/SBOM-sg-SEPIA/HEAD/Presentations/20240912_BFOSS24/bfoss24-Praes-Kern-SEPIA-SBOM-Exchange-Procedures-Interfaces-and-Architecture.pdf -------------------------------------------------------------------------------- /Tools/sbom-public-ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/main.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 5 | 6 | import { AppModule } from './app/app.module'; 7 | 8 | 9 | platformBrowserDynamic().bootstrapModule(AppModule) 10 | .catch(err => console.error(err)); 11 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | max-http-header-size: '10000000' 3 | port: 9051 4 | ssl: 5 | enabled: 'false' 6 | spring: 7 | application: 8 | name: sbom-utils-service 9 | servlet: 10 | multipart: 11 | max-file-size: 100MB 12 | max-request-size: 200MB 13 | jmx: 14 | default-domain: sbom-utils-service 15 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { Component } from '@angular/core'; 5 | 6 | @Component({ 7 | selector: 'app-root', 8 | templateUrl: './app.component.html', 9 | styleUrl: './app.component.css' 10 | }) 11 | export class AppComponent { 12 | title = 'S E P I A'; 13 | } 14 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | backend: 5 | build: ./Tools/sbom-public-service 6 | container_name: sbom-backend 7 | ports: 8 | - "9051:9051" 9 | volumes: 10 | - ./data/sbom:/data/sbom 11 | 12 | frontend: 13 | build: ./Tools/sbom-public-ui 14 | container_name: sbom-frontend 15 | ports: 16 | - "4200:4200" 17 | depends_on: 18 | - backend 19 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/index.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | SBOM Validator 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/AuthTokenModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | @Getter 12 | @Setter 13 | @AllArgsConstructor 14 | public class AuthTokenModel { 15 | 16 | private String token; 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/reuse.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Free Software Foundation Europe e.V. 2 | # SPDX-License-Identifier: CC0-1.0 3 | name: REUSE Compliance Check 4 | 5 | on: 6 | pull_request: 7 | branches: 8 | - main 9 | push: 10 | branches: 11 | -main 12 | 13 | jobs: 14 | reuse-tool: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: REUSE Compliance Check 19 | uses: fsfe/reuse-action@v4 20 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/AuthModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | @Getter 12 | @Setter 13 | @AllArgsConstructor 14 | public class AuthModel { 15 | 16 | private String username; 17 | 18 | private String password; 19 | } 20 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | # Editor configuration, see https://editorconfig.org 6 | root = true 7 | 8 | [*] 9 | charset = utf-8 10 | indent_style = space 11 | indent_size = 2 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.ts] 16 | quote_type = single 17 | 18 | [*.md] 19 | max_line_length = off 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXHashModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | @Getter 13 | @Setter 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class CycloneDXHashModel { 17 | private String alg; 18 | private String content; 19 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXPropertyModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | @Getter 13 | @Setter 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class CycloneDXPropertyModel { 17 | private String value; 18 | private String name; 19 | } -------------------------------------------------------------------------------- /Tools/sbom-public-ui/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1: Build Angular app 2 | FROM node:20-bullseye 3 | 4 | # Update system packages to patch vulnerabilities 5 | RUN apt-get update && apt-get upgrade -y && apt-get clean 6 | 7 | WORKDIR /app 8 | 9 | # Copy package.json and package-lock.json 10 | COPY package*.json ./ 11 | 12 | # Install dependencies 13 | RUN npm install --legacy-peer-deps 14 | 15 | # Copy the rest of the project 16 | COPY . . 17 | 18 | # Build Angular app 19 | # RUN npx ng serve 20 | 21 | EXPOSE 4200 22 | 23 | CMD ["npx", "ng", "serve", "--host", "0.0.0.0", "--port", "4200"] -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/ErrorModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | @Getter 13 | @Setter 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class ErrorModel { 17 | 18 | private String errorKey; 19 | private String message; 20 | private String[] path; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { NgModule } from '@angular/core'; 5 | import { RouterModule, Routes } from '@angular/router'; 6 | import { SbomInputComponent } from './sbom-input/sbom-input.component'; 7 | 8 | const routes: Routes = [ 9 | { path: '', component: SbomInputComponent } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [RouterModule.forRoot(routes, {useHash: true})], 14 | exports: [RouterModule] 15 | }) 16 | export class AppRoutingModule { } 17 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXLicenseChoiceModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | import lombok.AllArgsConstructor; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | 13 | @Getter 14 | @Setter 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class CycloneDXLicenseChoiceModel { 18 | 19 | private CycloneDXLicenseModel license; 20 | private String expression; 21 | 22 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxStartEndPointerModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class SpdxStartEndPointerModel{ 19 | private String reference; 20 | private String offset; 21 | private String lineNumber; 22 | 23 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXOrganizationalContactModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | @Getter 13 | @Setter 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class CycloneDXOrganizationalContactModel{ 17 | 18 | private String name; 19 | private String email; 20 | private String phone; 21 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxSnippetsRangesModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | 9 | 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import lombok.NoArgsConstructor; 14 | import lombok.Setter; 15 | 16 | @Getter 17 | @Setter 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class SpdxSnippetsRangesModel{ 21 | private SpdxStartEndPointerModel startPointer; 22 | private SpdxStartEndPointerModel endPointer; 23 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.methodParameters=generate 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 6 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 7 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore 8 | org.eclipse.jdt.core.compiler.processAnnotations=enabled 9 | org.eclipse.jdt.core.compiler.release=disabled 10 | org.eclipse.jdt.core.compiler.source=1.8 11 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/SbomUtilsServiceApplication.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils; 6 | 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | 10 | /** 11 | * 12 | * 13 | * 14 | */ 15 | 16 | 17 | @SpringBootApplication 18 | public class SbomUtilsServiceApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(SbomUtilsServiceApplication.class, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/DefaultWebResponse.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Component 15 | @Getter 16 | @Setter 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class DefaultWebResponse { 20 | 21 | private String message; 22 | private String data; 23 | private String status; 24 | } -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 | 7 |
8 |
9 |
10 | 11 |
12 | 13 |
14 |
15 |
16 |
17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxPackageVerificationCodeModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | 15 | @Getter 16 | @Setter 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class SpdxPackageVerificationCodeModel { 20 | private List packageVerificationCodeExcludedFiles; 21 | private String packageVerificationCodeValue; 22 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXOrganizationalEntityModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class CycloneDXOrganizationalEntityModel { 19 | private String name; 20 | private List url; 21 | private List contact; 22 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/ChangeLog.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Getter 17 | @Setter 18 | 19 | public class ChangeLog { 20 | 21 | private String fileName; 22 | private String lineNumber; 23 | private List changeDetails; 24 | private String op; 25 | private String path; 26 | private String value; 27 | } 28 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXToolModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class CycloneDXToolModel { 19 | private String vendor; 20 | private String name; 21 | private String version; 22 | private List hashes; 23 | private List externalReferences; 24 | } -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | 4 | 5 | ©2025 Robert Bosch GmbH. 6 | 7 | ©2025 Bosch Building Technologies - Bosch Sicherheitssysteme GmbH. 8 | 9 | ©2025 Bosch Global Software Technologies Private Limited. 10 | 11 | # Contributors 12 | 13 | Gopalakrishnan, Indhumathy (Gopalakrishnan.Indhumathy@in.bosch.com) 14 | 15 | K, Manoj (Manoj.Kammukalam@in.bosch.com) 16 | 17 | Kern, Hans Malte (hansmalte.kern@de.bosch.com) 18 | 19 | Meisenecker, Robert (Robert.Meisenecker@de.bosch.com) 20 | 21 | Prabhakaran, Rakesh (prabhakaran.rakesh@in.bosch.com) 22 | 23 | Wiens, Nikolai (Nikolai.Wiens@de.bosch.com) 24 | 25 | Slavov, Vladimir (vladimir.slavov@bosch.com) 26 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/DataWebResponse.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import org.springframework.stereotype.Component; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import lombok.NoArgsConstructor; 14 | import lombok.Setter; 15 | 16 | @Component 17 | @Getter 18 | @Setter 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | public class DataWebResponse { 22 | 23 | private String message; 24 | private String status; 25 | private List data; 26 | int recordsFiltered; 27 | int recordsTotal; 28 | int draw; 29 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | sbom.upload.path=c:\\temp\\sbom\\ 2 | 3 | 4 | # Max file size. 5 | #spring.servlet.multipart.max-file-size=10MB 6 | # Max request size. 7 | #spring.servlet.multipart.maxRequestSize=50MB 8 | 9 | server.tomcat.max-http-form-post-size=100MB 10 | 11 | spring.servlet.multipart.max-file-size=100MB 12 | spring.servlet.multipart.max-request-size=100MB 13 | 14 | sbom.input.path=c:\\downloads\\sbom\\ 15 | 16 | 17 | #proxy.url= 18 | #proxy.port= 19 | 20 | ##Configuration for SSL 21 | #server.port: 22 | #server.ssl.key-store: 23 | #server.ssl.key-store-password: 24 | #server.ssl.keyStoreType: 25 | #server.ssl.keyAlias: 26 | 27 | 28 | ##Configuration for SSO 29 | #server.servlet.context-path= 30 | #server.host.name= 31 | 32 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/BomStatusDisplayModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | import lombok.AllArgsConstructor; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | 13 | @Getter 14 | @Setter 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class BomStatusDisplayModel { 18 | private static final long serialVersionUID = 1L; 19 | 20 | private Integer pkBomDetailsId; 21 | private String bomFileversion; 22 | private String bomFormat; 23 | private String bomFilename; 24 | private String validStatus; 25 | private String creationDate; 26 | private String displayName; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXExternalReferenceModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import org.cyclonedx.model.ExternalReference.Type; 8 | 9 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import lombok.NoArgsConstructor; 14 | import lombok.Setter; 15 | 16 | @Getter 17 | @Setter 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class CycloneDXExternalReferenceModel { 21 | 22 | private String url; 23 | @JacksonXmlProperty(localName = "type", isAttribute = true) 24 | private Type type; 25 | private String comment; 26 | 27 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxReviewedsModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import com.fasterxml.jackson.annotation.JsonInclude; 8 | import com.fasterxml.jackson.annotation.JsonProperty; 9 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 10 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 11 | 12 | import lombok.AllArgsConstructor; 13 | import lombok.Getter; 14 | import lombok.NoArgsConstructor; 15 | import lombok.Setter; 16 | 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class SpdxReviewedsModel{ 23 | private String reviewer; 24 | private String reviewDate; 25 | private String comment; 26 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/BomFileDetailsModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.sql.Timestamp; 8 | 9 | 10 | import lombok.AllArgsConstructor; 11 | import lombok.Getter; 12 | import lombok.NoArgsConstructor; 13 | import lombok.Setter; 14 | 15 | @Getter 16 | @Setter 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class BomFileDetailsModel { 20 | private Integer pkBomDetailsId; 21 | private String bomFilecontent; 22 | private String bomFileversion; 23 | private String bomFormat; 24 | private String bomFilename; 25 | private String validStatus; 26 | private Timestamp creationDate; 27 | private String schemaFilecontent; 28 | private String reqtype; 29 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1: Build Java app with Maven 2 | FROM maven:3.8.6-openjdk-8 3 | 4 | WORKDIR /app 5 | 6 | # Copy pom.xml and download dependencies first (better caching) 7 | COPY pom.xml . 8 | RUN mvn dependency:go-offline -B 9 | 10 | # Copy source and build JAR 11 | COPY src ./src 12 | RUN mvn clean install -DskipTests 13 | 14 | # Stage 2: Run Spring Boot app 15 | # FROM openjdk:8-jre-slim 16 | 17 | # WORKDIR /app 18 | 19 | # Copy JAR from build stage 20 | # COPY --from=build /app/target/sbom-public-*.jar app.jar 21 | 22 | # Create upload folder 23 | RUN mkdir -p /data/sbom 24 | 25 | # Set the sbom.upload.path property 26 | ENV SBOM_UPLOAD_PATH=/data/sbom 27 | 28 | EXPOSE 9051 29 | 30 | # ENTRYPOINT ["java", "-jar", "/app/target/sbom-public-*.jar", "--sbom.upload.path=/data/sbom"] 31 | ENTRYPOINT ["mvn", "spring-boot:run"] -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/BomStatusModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class BomStatusModel { 19 | private static final long serialVersionUID = 1L; 20 | 21 | private Integer pkBomDetailsId; 22 | private String bomFilecontent; 23 | private String bomFileversion; 24 | private String bomFormat; 25 | private String bomFilename; 26 | private String validStatus; 27 | private String creationDate; 28 | private String displayName; 29 | private String schemaFilecontent; 30 | } 31 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/footer/footer.component.spec.ts: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | // SPDX-License-Identifier: MIT 4 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 5 | 6 | import { FooterComponent } from './footer.component'; 7 | 8 | describe('FooterComponent', () => { 9 | let component: FooterComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [ FooterComponent ] 15 | }) 16 | .compileComponents(); 17 | }); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(FooterComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/header/header.component.spec.ts: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | // SPDX-License-Identifier: MIT 4 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 5 | 6 | import { HeaderComponent } from './header.component'; 7 | 8 | describe('HeaderComponent', () => { 9 | let component: HeaderComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async () => { 13 | await TestBed.configureTestingModule({ 14 | declarations: [ HeaderComponent ] 15 | }) 16 | .compileComponents(); 17 | }); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(HeaderComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { Component, OnInit } from '@angular/core'; 5 | import { SbomInputService } from '../services/sbom-input.service'; 6 | import { RestEndpointsService } from '../services/rest-endpoints.service'; 7 | @Component({ 8 | selector: 'app-footer', 9 | templateUrl: './footer.component.html', 10 | styleUrls: ['./footer.component.css'] 11 | }) 12 | export class FooterComponent implements OnInit { 13 | 14 | 15 | constructor(public sbomInputService: SbomInputService,public restEndPointService:RestEndpointsService) { } 16 | 17 | ngOnInit(): void { 18 | } 19 | 20 | downloadUserManual() { 21 | const url = this.restEndPointService.downloadUserManual; // Replace with your actual URL 22 | window.open(url, '_blank'); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXMetaDataModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | import lombok.AllArgsConstructor; 11 | import lombok.Getter; 12 | import lombok.NoArgsConstructor; 13 | import lombok.Setter; 14 | 15 | @Getter 16 | @Setter 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class CycloneDXMetaDataModel { 20 | 21 | private Date timestamp = new Date(); 22 | private List tools; 23 | private CycloneDXOrganizationalEntityModel supplier; 24 | private CycloneDXComponentModel component; 25 | private List properties; 26 | public CycloneDXOrganizationalEntityModel getSupplier() { 27 | return supplier; 28 | } 29 | } -------------------------------------------------------------------------------- /Tools/sbom-public-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. 6 | 7 | # Compiled output 8 | /dist 9 | /tmp 10 | /out-tsc 11 | /bazel-out 12 | 13 | # Node 14 | /node_modules 15 | npm-debug.log 16 | yarn-error.log 17 | 18 | # IDEs and editors 19 | .idea/ 20 | .project 21 | .classpath 22 | .c9/ 23 | *.launch 24 | .settings/ 25 | *.sublime-workspace 26 | 27 | # Visual Studio Code 28 | .vscode/* 29 | !.vscode/settings.json 30 | !.vscode/tasks.json 31 | !.vscode/launch.json 32 | !.vscode/extensions.json 33 | .history/* 34 | 35 | # Miscellaneous 36 | /.angular/cache 37 | .sass-cache/ 38 | /connect.lock 39 | /coverage 40 | /libpeerconnection.log 41 | testem.log 42 | /typings 43 | 44 | # System files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | .app-content { 5 | position: relative; 6 | height: 100vh; 7 | /* left: 260px; */ 8 | width: calc(100% - 260px); 9 | transition: all 0.5s ease; 10 | } 11 | 12 | .sidebar.close~.app-content { 13 | left: 78px; 14 | width: calc(100% - 78px); 15 | } 16 | 17 | .app-content .sbominput-content { 18 | height: 60px; 19 | display: flex; 20 | align-items: center; 21 | } 22 | 23 | .app-content .sbominput-content .bx-menu, 24 | .app-content .sbominput-content .text { 25 | color: #004768; 26 | font-size: 35px; 27 | } 28 | 29 | .app-content .sbominput-content .bx-menu { 30 | margin: 0 15px; 31 | cursor: pointer; 32 | } 33 | 34 | .app-content .sbominput-content .text { 35 | font-size: 26px; 36 | font-weight: 600; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "outDir": "./dist/out-tsc", 6 | "strict": true, 7 | "noImplicitOverride": true, 8 | "noPropertyAccessFromIndexSignature": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "target": "ES2022", 19 | "module": "ES2022", 20 | "useDefineForClassFields": false, 21 | "lib": [ 22 | "ES2022", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/ComponentStatusModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | @Getter 13 | @Setter 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class ComponentStatusModel { 17 | 18 | private static final long serialVersionUID = 1L; 19 | 20 | private Integer pkAllowlistMasterId; 21 | 22 | private Integer componentId; 23 | 24 | private Integer woId; 25 | 26 | private String componentName; 27 | 28 | private String version; 29 | 30 | private String division; 31 | 32 | private String requestorName; 33 | 34 | private String requestedDate; 35 | 36 | private String eSignature; 37 | 38 | private String license; 39 | 40 | private String status; 41 | 42 | private String os; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXLicenseModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | import org.cyclonedx.model.AttachmentText; 9 | 10 | import com.fasterxml.jackson.annotation.JsonProperty; 11 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; 12 | 13 | import lombok.AllArgsConstructor; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | import lombok.Setter; 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class CycloneDXLicenseModel { 23 | 24 | @JacksonXmlProperty(localName = "id") 25 | @JsonProperty("id") 26 | private String id; 27 | private String name; 28 | private String url; 29 | 30 | @JacksonXmlProperty(localName = "text") 31 | @JsonProperty("text") 32 | private AttachmentText attachmentText; 33 | 34 | 35 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxSnippetModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import javax.annotation.Generated; 12 | 13 | 14 | import lombok.AllArgsConstructor; 15 | import lombok.Getter; 16 | import lombok.NoArgsConstructor; 17 | import lombok.Setter; 18 | 19 | @Getter 20 | @Setter 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | public class SpdxSnippetModel{ 24 | private String SPDXID; 25 | private List annotations; 26 | private List attributionTexts; 27 | private String comment; 28 | private String copyrightText; 29 | private String licenseComments; 30 | private String licenseConcluded; 31 | private List licenseInfoInSnippets; 32 | private String name; 33 | private List ranges; 34 | private String snippetFromFile; 35 | 36 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxCreationInfoModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.Date; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class SpdxCreationInfoModel { 19 | private String created; 20 | private String comment; 21 | private String[] creators; 22 | private String licenseListVersion; 23 | 24 | public void setcreated(String created) { 25 | this.created = created; 26 | } 27 | 28 | public void setcomment(String comment) { 29 | this.comment = comment; 30 | 31 | } 32 | 33 | public void setcreators(String[] creators) { 34 | this.creators = creators; 35 | } 36 | 37 | public void setlicenseListVersion(String licenseListVersion) { 38 | this.licenseListVersion = licenseListVersion; 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 | associated documentation files (the "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the 9 | following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial 12 | portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 15 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 16 | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 18 | USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | sbom-utils-service 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.springframework.ide.eclipse.boot.validation.springbootbuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.m2e.core.maven2Builder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.jdt.core.javanature 26 | org.eclipse.m2e.core.maven2Nature 27 | 28 | 29 | 30 | 1749031439842 31 | 32 | 30 33 | 34 | org.eclipse.core.resources.regexFilterMatcher 35 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/footer/footer.component.css: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | .sbom-footer-nav footer { 5 | background-color: #ffffff; 6 | border-top: 1px solid #e6e6e6; 7 | margin-top: 1rem; 8 | box-sizing: border-box; 9 | } 10 | 11 | .sbom-footer-nav footer.sticky { 12 | position: fixed; 13 | bottom: 0; 14 | width: 100%; 15 | } 16 | .sbom-footer-nav nav { 17 | display: inline-block; 18 | } 19 | .sbom-footer-nav nav a { 20 | display: inline-block; 21 | font-size: 0.875rem; 22 | padding: 1rem; 23 | } 24 | .sbom-footer-nav .footer-placeholder { 25 | display: none; 26 | } 27 | .sbom-footer-nav footer.sticky ~ .footer-placeholder { 28 | display: block; 29 | } 30 | .sbom-footer-nav .copyright { 31 | padding: 1rem; 32 | font-weight: bold; 33 | font-size: 0.875rem; 34 | } 35 | .container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { 36 | --bs-gutter-x: 1.0rem; 37 | --bs-gutter-y: 0; 38 | width: 100%; 39 | padding-right: calc(var(--bs-gutter-x) * .5); 40 | padding-left: calc(var(--bs-gutter-x) * .5); 41 | margin-right: auto; 42 | margin-left: auto; 43 | } 44 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SBOMInputModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import com.google.gson.annotations.Expose; 8 | import com.google.gson.annotations.SerializedName; 9 | 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @NoArgsConstructor 15 | @Getter 16 | @Setter 17 | public class SBOMInputModel { 18 | 19 | @SerializedName("apiKey") 20 | @Expose 21 | private String apiKey; 22 | 23 | @SerializedName("scanCode") 24 | @Expose 25 | private String scanCode; 26 | 27 | @SerializedName("reqType") 28 | @Expose 29 | private String reqType; 30 | 31 | @SerializedName("selVersion") 32 | @Expose 33 | private Object selVersion; 34 | 35 | @SerializedName("servers") 36 | @Expose 37 | private String servers; 38 | 39 | @SerializedName("workon") 40 | @Expose 41 | private String workon; 42 | 43 | @SerializedName("bomfile") 44 | @Expose 45 | private String bomfile; 46 | 47 | @SerializedName("schemafile") 48 | @Expose 49 | private String schemafile; 50 | 51 | @SerializedName("cmpList") 52 | @Expose 53 | private Integer[] cmpList; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxPackageExternalRefsModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import javax.annotation.Generated; 10 | 11 | import com.fasterxml.jackson.annotation.JsonProperty; 12 | 13 | import lombok.AllArgsConstructor; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | import lombok.Setter; 17 | 18 | 19 | @Getter 20 | @Setter 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | public class SpdxPackageExternalRefsModel { 24 | private String referenceLocator; 25 | private String referenceType; 26 | private ReferenceCategory referenceCategory; 27 | private String comment; 28 | 29 | @Generated("jsonschema2pojo") 30 | public enum ReferenceCategory { 31 | 32 | OTHER("OTHER"), 33 | PERSISTENT_ID("PERSISTENT_ID"), 34 | SECURITY("SECURITY"), 35 | PACKAGE_MANAGER("PACKAGE_MANAGER"); 36 | 37 | private final String name; 38 | 39 | public String getReferenceCategory() { 40 | return this.name; 41 | } 42 | 43 | ReferenceCategory(String name) { 44 | this.name = name; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Schema/SPDX/Bosch_SEPIA/bosch_sepia_spdx_2.3.md: -------------------------------------------------------------------------------- 1 | ## SPDX_2.3 2 | 3 | | Root Element | Child Element | | 4 | |:------------------|:----------------------|:------------------| 5 | | | | | 6 | | spdxVersion | | | 7 | | documentNamespace | | | 8 | | dataLicense | | | 9 | | creationInfo | created | | 10 | | | creators | | 11 | | | | | 12 | | packages | externalRefs | referenceLocator | 13 | | | | referenceCategory | 14 | | | | referenceType | 15 | | | | comment | 16 | | | name | | 17 | | | versionInfo | | 18 | | | primaryPackagePurpose | | 19 | | | licenseDeclared | | 20 | | | copyrightText | | 21 | 22 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/README.md: -------------------------------------------------------------------------------- 1 | 4 | # SbomUtilsUi 5 | 6 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.8. 7 | 8 | ## Development server 9 | 10 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 11 | 12 | ## Code scaffolding 13 | 14 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 15 | 16 | ## Build 17 | 18 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 19 | 20 | ## Running unit tests 21 | 22 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 23 | 24 | ## Running end-to-end tests 25 | 26 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 27 | 28 | ## Further help 29 | 30 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 31 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { NgModule } from '@angular/core'; 5 | import { BrowserModule } from '@angular/platform-browser'; 6 | import { FormsModule } from '@angular/forms'; 7 | 8 | import { AppRoutingModule } from './app-routing.module'; 9 | import { AppComponent } from './app.component'; 10 | 11 | import { FooterComponent } from './footer/footer.component'; 12 | import { HeaderComponent } from './header/header.component'; 13 | import { SbomInputComponent } from './sbom-input/sbom-input.component'; 14 | import { HttpClientModule } from '@angular/common/http'; 15 | import { NgxJsonViewerModule } from 'ngx-json-viewer'; 16 | import { TabsModule } from 'ngx-bootstrap/tabs'; 17 | import { NgJsonEditorModule } from 'ang-jsoneditor' 18 | 19 | @NgModule({ 20 | declarations: [ 21 | AppComponent, 22 | HeaderComponent, 23 | FooterComponent, 24 | SbomInputComponent 25 | ], 26 | imports: [ 27 | BrowserModule, 28 | AppRoutingModule, 29 | FormsModule, 30 | HttpClientModule, 31 | NgxJsonViewerModule, 32 | TabsModule.forRoot(), 33 | NgJsonEditorModule 34 | 35 | ], 36 | providers: [], 37 | bootstrap: [AppComponent] 38 | }) 39 | export class AppModule { } 40 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/services/health-check.service.ts: -------------------------------------------------------------------------------- 1 | // health-check.service.ts 2 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 3 | 4 | SPDX-License-Identifier: MIT */ 5 | import { Injectable } from '@angular/core'; 6 | import { HttpClient,HttpHeaders } from '@angular/common/http'; 7 | import { Observable, of } from 'rxjs'; 8 | import { catchError } from 'rxjs/operators'; 9 | import { RestEndpointsService } from './rest-endpoints.service'; 10 | 11 | @Injectable({ 12 | providedIn: 'root' 13 | }) 14 | export class HealthCheckService { 15 | private healthCheckUrl = '/api/health-check'; // Replace with your actual health check API endpoint 16 | 17 | constructor(private http: HttpClient,private restEndPointService: RestEndpointsService) {} 18 | 19 | checkServerHealth(): Observable { 20 | const headers = new HttpHeaders({ 21 | 'Content-Type': 'application/json', 22 | 'Access-Control-Allow-Origin': '*', 23 | 'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS', 24 | 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token' 25 | }); 26 | 27 | return this.http.get(this.restEndPointService.healthCheckup,{ headers }).pipe( 28 | catchError(() => { 29 | return of({ status: 'Server is down' }); 30 | }) 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { TestBed } from '@angular/core/testing'; 5 | import { RouterTestingModule } from '@angular/router/testing'; 6 | import { AppComponent } from './app.component'; 7 | 8 | describe('AppComponent', () => { 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | imports: [ 12 | RouterTestingModule 13 | ], 14 | declarations: [ 15 | AppComponent 16 | ], 17 | }).compileComponents(); 18 | }); 19 | 20 | it('should create the app', () => { 21 | const fixture = TestBed.createComponent(AppComponent); 22 | const app = fixture.componentInstance; 23 | expect(app).toBeTruthy(); 24 | }); 25 | 26 | it(`should have as title 'sbom-utils-ui'`, () => { 27 | const fixture = TestBed.createComponent(AppComponent); 28 | const app = fixture.componentInstance; 29 | expect(app.title).toEqual('sbom-utils-ui'); 30 | }); 31 | 32 | it('should render title', () => { 33 | const fixture = TestBed.createComponent(AppComponent); 34 | fixture.detectChanges(); 35 | const compiled = fixture.nativeElement as HTMLElement; 36 | expect(compiled.querySelector('h1')?.textContent).toContain('Hello, sbom-utils-ui'); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXInputModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | import java.util.List; 9 | 10 | import org.cyclonedx.model.JsonOnly; 11 | 12 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; 13 | 14 | import lombok.AllArgsConstructor; 15 | import lombok.Getter; 16 | import lombok.NoArgsConstructor; 17 | import lombok.Setter; 18 | 19 | @Getter 20 | @Setter 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | public class CycloneDXInputModel { 24 | 25 | @JacksonXmlProperty(isAttribute = true) 26 | private int version = 1; 27 | 28 | @JacksonXmlProperty(isAttribute = true) 29 | private String serialNumber; 30 | 31 | @JsonOnly 32 | private String specVersion; 33 | 34 | @JsonOnly 35 | private String bomFormat; 36 | 37 | private CycloneDXMetaDataModel metadata; 38 | 39 | private List components; 40 | 41 | public void setVersion(int version) { 42 | this.version = version; 43 | } 44 | 45 | public void setspecVersion(String specVersion) { 46 | this.specVersion = specVersion; 47 | } 48 | 49 | public void setBomFormat(String bomFormat) { 50 | this.bomFormat = bomFormat; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/exception/CycloneConversionException.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.exception; 6 | public class CycloneConversionException extends Exception { 7 | 8 | /** 9 | * 10 | */ 11 | private static final long serialVersionUID = 1L; 12 | 13 | /** 14 | * 15 | */ 16 | public CycloneConversionException() { 17 | super(); 18 | } 19 | 20 | /** 21 | * @param message 22 | */ 23 | public CycloneConversionException(String message) { 24 | super(message); 25 | } 26 | 27 | /** 28 | * @param cause 29 | */ 30 | public CycloneConversionException(Throwable cause) { 31 | super(cause); 32 | } 33 | 34 | /** 35 | * @param message 36 | * @param cause 37 | */ 38 | public CycloneConversionException(String message, Throwable cause) { 39 | super(message, cause); 40 | } 41 | 42 | /** 43 | * @param message 44 | * @param cause 45 | * @param enableSuppression 46 | * @param writableStackTrace 47 | */ 48 | public CycloneConversionException(String message, Throwable cause, boolean enableSuppression, 49 | boolean writableStackTrace) { 50 | super(message, cause, enableSuppression, writableStackTrace); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/header/header.component.html: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 | 11 |
12 |
13 |
14 |
15 | 19 |
20 |
21 |
22 | 23 |
24 | 25 | 28 | 29 |
30 |
31 | 32 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /DCO.txt: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 6 | Everyone is permitted to copy and distribute verbatim copies of this 7 | license document, but changing it is not allowed. 8 | 9 | 10 | Developer's Certificate of Origin 1.1 11 | 12 | By making a contribution to this project, I certify that: 13 | 14 | (a) The contribution was created in whole or in part by me and I 15 | have the right to submit it under the open source license 16 | indicated in the file; or 17 | 18 | (b) The contribution is based upon previous work that, to the best 19 | of my knowledge, is covered under an appropriate open source 20 | license and I have the right under that license to submit that 21 | work with modifications, whether created in whole or in part 22 | by me, under the same open source license (unless I am 23 | permitted to submit under a different license), as indicated 24 | in the file; or 25 | 26 | (c) The contribution was provided directly to me by some other 27 | person who certified (a), (b) or (c) and I have not modified 28 | it. 29 | 30 | (d) I understand and agree that this project and the contribution 31 | are public and that a record of the contribution (including all 32 | personal information I submit with it, including my sign-off) is 33 | maintained indefinitely and may be redistributed consistent with 34 | this project or the open source license(s) involved. 35 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/exception/InvalidFileNameException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2021 Source Auditor Inc. 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | package com.sepia.sbomutils.exception; 7 | 8 | /** 9 | * @author Gary O'Neall 10 | * 11 | */ 12 | public class InvalidFileNameException extends Exception { 13 | 14 | /** 15 | * 16 | */ 17 | private static final long serialVersionUID = 1L; 18 | 19 | /** 20 | * 21 | */ 22 | public InvalidFileNameException() { 23 | super(); 24 | } 25 | 26 | /** 27 | * @param message 28 | */ 29 | public InvalidFileNameException(String message) { 30 | super(message); 31 | } 32 | 33 | /** 34 | * @param cause 35 | */ 36 | public InvalidFileNameException(Throwable cause) { 37 | super(cause); 38 | } 39 | 40 | /** 41 | * @param message 42 | * @param cause 43 | */ 44 | public InvalidFileNameException(String message, Throwable cause) { 45 | super(message, cause); 46 | } 47 | 48 | /** 49 | * @param message 50 | * @param cause 51 | * @param enableSuppression 52 | * @param writableStackTrace 53 | */ 54 | public InvalidFileNameException(String message, Throwable cause, boolean enableSuppression, 55 | boolean writableStackTrace) { 56 | super(message, cause, enableSuppression, writableStackTrace); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/services/rest-endpoints.service.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | import { Injectable } from '@angular/core'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class RestEndpointsService { 10 | 11 | constructor() { } 12 | 13 | 14 | private endpoint = 'http://localhost:9051/'; 15 | 16 | 17 | 18 | public uploadFile: string = this.endpoint + 'uploadInputFile'; 19 | public validateFiles: string = this.endpoint + 'validateSboms'; 20 | public deleteSbomEntry: string = this.endpoint + 'deleteSbomEntry'; 21 | public clearSession: string = this.endpoint + 'clearSession'; 22 | public fetchErrorDetails: string = this.endpoint + 'fetchErrorDetails'; 23 | public fetchJsonContent: string = this.endpoint + 'fetchJsonContent'; 24 | public mergeCyclonedx: string = this.endpoint + 'mergeCyclonedx'; 25 | public mergeSpdx: string = this.endpoint + 'mergeSpdx'; 26 | public replaceFile: string = this.endpoint + 'replaceFile'; 27 | public getJsonDifferences: string = this.endpoint + 'getJsonDifferences'; 28 | public prepareForDownload: string = this.endpoint + 'prepareForDownload'; 29 | public convertSbom: string = this.endpoint + 'convertSbom'; 30 | public fetchSbomFromFossid: string = this.endpoint + 'fetchSbomFromFossid'; 31 | public healthCheckup: string = this.endpoint + 'health'; 32 | public downloadUserManual: string = this.endpoint + 'downloadUserManual'; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-scancode-dco-1.1.txt: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 6 | Everyone is permitted to copy and distribute verbatim copies of this 7 | license document, but changing it is not allowed. 8 | 9 | 10 | Developer's Certificate of Origin 1.1 11 | 12 | By making a contribution to this project, I certify that: 13 | 14 | (a) The contribution was created in whole or in part by me and I 15 | have the right to submit it under the open source license 16 | indicated in the file; or 17 | 18 | (b) The contribution is based upon previous work that, to the best 19 | of my knowledge, is covered under an appropriate open source 20 | license and I have the right under that license to submit that 21 | work with modifications, whether created in whole or in part 22 | by me, under the same open source license (unless I am 23 | permitted to submit under a different license), as indicated 24 | in the file; or 25 | 26 | (c) The contribution was provided directly to me by some other 27 | person who certified (a), (b) or (c) and I have not modified 28 | it. 29 | 30 | (d) I understand and agree that this project and the contribution 31 | are public and that a record of the contribution (including all 32 | personal information I submit with it, including my sign-off) is 33 | maintained indefinitely and may be redistributed consistent with 34 | this project or the open source license(s) involved. 35 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/sbom-input/sbom-input.model.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | export class UploadModel { 5 | inputType!: string; 6 | schemaType!: string; 7 | schemaVersion!: string; 8 | sbomFile!: File; 9 | schemaFile!: File; 10 | index!: number; 11 | schema!: boolean; 12 | timestamp!: any; 13 | hidden!: boolean; 14 | sbomFileName!: string; 15 | schemaFileName!: string; 16 | valid!: boolean; 17 | filePath!: string; 18 | errorDetails: ErrorModel[] = []; 19 | sbomJsonString!: string; 20 | schemaJsonString!: string; 21 | dirName!: string; 22 | sbomJson!: any; 23 | schemaJson!: any; 24 | changeLogsList: ChangeLog[] = []; 25 | fileHash!: string; 26 | customErrorDetails: ErrorModel[] = []; 27 | fossidServer!: String; 28 | apiKey!: String; 29 | scanCode!: String; 30 | ntid!:String; 31 | message!:string; 32 | status!: number; 33 | } 34 | 35 | export class ErrorModel { 36 | errorKey!: string; 37 | message!: string; 38 | path!: String[]; 39 | } 40 | 41 | export class ChangeLog { 42 | fileName!: string; 43 | lineNumber!: string; 44 | changeDetails: string[] = []; 45 | op!: string; 46 | path!: string; 47 | value!: string; 48 | oldvalue!: string; 49 | } 50 | 51 | export class AuditLog { 52 | userId!: string; 53 | action!: string; 54 | fileName!: string; 55 | fileHash!: string; 56 | timestamp!: string; 57 | status!: string; 58 | } 59 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/CorsFilter.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils; 6 | 7 | import java.io.IOException; 8 | 9 | import javax.servlet.Filter; 10 | import javax.servlet.FilterChain; 11 | import javax.servlet.FilterConfig; 12 | import javax.servlet.ServletException; 13 | import javax.servlet.ServletRequest; 14 | import javax.servlet.ServletResponse; 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | 18 | import org.springframework.core.Ordered; 19 | import org.springframework.core.annotation.Order; 20 | import org.springframework.http.HttpMethod; 21 | import org.springframework.stereotype.Component; 22 | 23 | @Component 24 | 25 | @Order(Ordered.HIGHEST_PRECEDENCE) 26 | public class CorsFilter implements Filter { 27 | 28 | @Override 29 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 30 | throws IOException, ServletException { 31 | final HttpServletResponse response = (HttpServletResponse) res; 32 | response.setHeader("Access-Control-Allow-Origin", "*"); 33 | response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE"); 34 | response.setHeader("Access-Control-Allow-Headers", "*"); 35 | response.setHeader("Access-Control-Max-Age", "3600"); 36 | if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { 37 | response.setStatus(HttpServletResponse.SC_OK); 38 | } else { 39 | chain.doFilter(req, res); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/styles/global.scss: -------------------------------------------------------------------------------- 1 | /* autoprefixer grid: on */ 2 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 3 | 4 | SPDX-License-Identifier: MIT */ 5 | @import 'imports.scss'; 6 | @import 'variables/font-face.scss'; 7 | @import 'base/typography.scss'; 8 | @import 'base/icons.scss'; 9 | @import 'base/layout.scss'; 10 | @import 'base/basic.scss'; 11 | @import 'base/button.scss'; 12 | @import 'components/loading-spinner.component'; 13 | @import 'components/dropdown.component'; 14 | @import 'components/footer-nav.component'; 15 | @import 'components/full-header.component'; 16 | @import 'components/language-selector.component'; 17 | @import 'components/navigation.component'; 18 | @import 'components/popover.component'; 19 | @import 'components/breadcrumbs.component'; 20 | @import 'components/form-radio.component'; 21 | @import 'components/form-checkbox.component'; 22 | @import 'components/form-chips-input.component'; 23 | @import 'components/form-switch.component'; 24 | @import 'components/modal.component'; 25 | @import 'components/search-result.component'; 26 | @import 'components/tab-panel.component'; 27 | @import 'components/callout.component'; 28 | @import 'components/teaser-panel.component'; 29 | @import 'components/board-item.component'; 30 | @import 'components/accordion.component'; 31 | @import 'components/progress-indicator.component'; 32 | @import '~flatpickr/dist/flatpickr.css'; 33 | @import 'overwrites/flatpickr.scss'; 34 | 35 | .supergraphic { 36 | background-repeat: no-repeat; 37 | background-size: cover; 38 | background-position: center center; 39 | background-image: url($supergraphic-path--xs); 40 | } 41 | 42 | .supergraphic.bar { 43 | height: 14px; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxExternalDocumentRefModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import com.fasterxml.jackson.annotation.JsonProperty; 8 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 9 | 10 | import lombok.AllArgsConstructor; 11 | import lombok.Getter; 12 | import lombok.NoArgsConstructor; 13 | import lombok.Setter; 14 | 15 | @Getter 16 | @Setter 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | 20 | public class SpdxExternalDocumentRefModel { 21 | 22 | @JsonProperty("checksum") 23 | @JsonPropertyDescription("A Checksum is value that allows the contents of a file to be authenticated. Even small changes to the content of the file will change its checksum. This class allows the results of a variety of checksum and cryptographic message digest algorithms to be represented.") 24 | private SpdxPackageChecksumsModel checksum; 25 | /** 26 | * externalDocumentId is a string containing letters, numbers, ., - and/or + which uniquely identifies an external document within this document. 27 | * 28 | */ 29 | @JsonProperty("externalDocumentId") 30 | @JsonPropertyDescription("externalDocumentId is a string containing letters, numbers, ., - and/or + which uniquely identifies an external document within this document.") 31 | private String externalDocumentId; 32 | /** 33 | * SPDX ID for SpdxDocument. A property containing an SPDX document. 34 | * 35 | */ 36 | @JsonProperty("spdxDocument") 37 | @JsonPropertyDescription("SPDX ID for SpdxDocument. A property containing an SPDX document.") 38 | private String spdxDocument; 39 | 40 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/README.md: -------------------------------------------------------------------------------- 1 | 4 | ## **SBOM Validator** 5 | 6 | **SBOM Validator** is a comprehensive tool designed for managing and 7 | streamlining Software Bill of Materials (SBOM) files. It supports 8 | operations such as **validation**, **editing**, **merging**, 9 | **comparison**, and **conversion** of SBOMs in JSON formats like 10 | **CycloneDX 1.4** and **SPDX 2.3**. 11 | 12 | Developed using **Java Spring Boot** (backend) and **Angular** 13 | (frontend), SBOM Validator ensures compliance with industry standards 14 | while enhancing interoperability and efficiency in managing SBOMs. 15 | 16 | ## Technologies 17 | 18 | Microservices npm 19 | TypeScript Apache Maven 20 | ANGULAR Docker 21 | SpringBoot swagger 22 | 23 | 24 | 25 | ## Key Features 26 | 27 | - **Validation**: Ensure SBOM files conform to CycloneDX and SPDX 28 | standards. 29 | 30 | - **Editing**: Modify SBOM entries, including components and 31 | dependencies. 32 | 33 | - **Merging**: Combine multiple SBOM files into a single, unified 34 | document. 35 | 36 | 37 | 38 | With its intuitive interface and robust functionality, SBOM Validator 39 | simplifies SBOM management, ensuring software supply chain transparency, 40 | compliance, and security. 41 | 42 | ## User Interface 43 | 44 | ![](./images/media/image2.png) 45 | The user can upload and validate the SBOM files and perform the merge operation. 46 | The session will clear all the uploaded file once reload the page. 47 | Download and keep Audit Log for future reference. 48 | 49 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/util/CustomMultipartFile.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | package com.sepia.sbomutils.util; 5 | 6 | import org.springframework.web.multipart.MultipartFile; 7 | import java.io.ByteArrayInputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | 11 | public class CustomMultipartFile implements MultipartFile { 12 | private final byte[] fileBytes; 13 | private final String fileName; 14 | private final String contentType; 15 | 16 | public CustomMultipartFile(byte[] fileBytes, String fileName, String contentType) { 17 | this.fileBytes = fileBytes; 18 | this.fileName = fileName; 19 | this.contentType = contentType; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return fileName; 25 | } 26 | 27 | @Override 28 | public String getOriginalFilename() { 29 | return fileName; 30 | } 31 | 32 | @Override 33 | public String getContentType() { 34 | return contentType; 35 | } 36 | 37 | @Override 38 | public boolean isEmpty() { 39 | return fileBytes == null || fileBytes.length == 0; 40 | } 41 | 42 | @Override 43 | public long getSize() { 44 | return fileBytes.length; 45 | } 46 | 47 | @Override 48 | public byte[] getBytes() throws IOException { 49 | return fileBytes; 50 | } 51 | 52 | @Override 53 | public InputStream getInputStream() throws IOException { 54 | return new ByteArrayInputStream(fileBytes); 55 | } 56 | 57 | @Override 58 | public void transferTo(java.io.File dest) throws IOException { 59 | // Implement if needed IllegalStateException 60 | } 61 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxAnnotationModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | import com.fasterxml.jackson.annotation.JsonProperty; 7 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 8 | 9 | import lombok.AllArgsConstructor; 10 | import lombok.Getter; 11 | import lombok.NoArgsConstructor; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class SpdxAnnotationModel { 19 | 20 | public enum AnnotationType { 21 | 22 | OTHER("OTHER"), 23 | REVIEW("REVIEW"); 24 | 25 | private final String name; 26 | 27 | public String getAnnotationTypeName() { 28 | return this.name; 29 | } 30 | 31 | AnnotationType(String name) { 32 | this.name = name; 33 | } 34 | } 35 | @JsonProperty("annotationDate") 36 | @JsonPropertyDescription("Identify when the comment was made. This is to be specified according to the combined date and time in the UTC format, as specified in the ISO 8601 standard.") 37 | private String annotationDate; 38 | /** 39 | * Type of the annotation. 40 | * 41 | */ 42 | @JsonProperty("annotationType") 43 | @JsonPropertyDescription("Type of the annotation.") 44 | private AnnotationType annotationType; 45 | /** 46 | * This field identifies the person, organization, or tool that has commented on a file, package, snippet, or the entire document. 47 | * 48 | */ 49 | @JsonProperty("annotator") 50 | @JsonPropertyDescription("This field identifies the person, organization, or tool that has commented on a file, package, snippet, or the entire document.") 51 | private String annotator; 52 | @JsonProperty("comment") 53 | private String comment; 54 | 55 | 56 | } -------------------------------------------------------------------------------- /Tools/sbom-public-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sbom-utils-ui", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^17.3.12", 14 | "@angular/cdk": "^18.1.4", 15 | "@angular/common": "^17.3.0", 16 | "@angular/compiler": "^17.3.0", 17 | "@angular/core": "^17.3.0", 18 | "@angular/forms": "^17.3.0", 19 | "@angular/material": "^18.1.4", 20 | "@angular/platform-browser": "^17.3.0", 21 | "@angular/platform-browser-dynamic": "^17.3.0", 22 | "@angular/router": "^17.3.0", 23 | "@fortawesome/fontawesome-free": "^6.7.2", 24 | "@ng-select/ng-select": "^13.7.0", 25 | "@types/jsoneditor": "^9.9.5", 26 | "ang-jsoneditor": "^3.1.1", 27 | "angular-jsoneditor": "^0.0.2", 28 | "bootstrap": "^5.3.3", 29 | "date-fns": "^3.6.0", 30 | "file-saver": "^2.0.5", 31 | "flatpickr": "^4.6.13", 32 | "jquery": "^3.7.1", 33 | "json-editor": "^0.7.28", 34 | "jsoneditor": "^10.1.0", 35 | "jspdf": "^2.5.2", 36 | "jspdf-autotable": "^3.8.4", 37 | "jszip": "^3.10.1", 38 | "ngx-bootstrap": "^18.0.2", 39 | "ngx-json-viewer": "^3.2.1", 40 | "rxjs": "~7.8.0", 41 | "tslib": "^2.3.0", 42 | "zone.js": "~0.14.3" 43 | }, 44 | "devDependencies": { 45 | "@angular-devkit/build-angular": "^17.3.8", 46 | "@angular/cli": "^17.3.8", 47 | "@angular/compiler-cli": "^17.3.0", 48 | "@types/file-saver": "^2.0.7", 49 | "@types/jasmine": "~5.1.0", 50 | "@types/jquery": "^3.5.30", 51 | "jasmine-core": "~5.1.0", 52 | "karma": "~6.4.0", 53 | "karma-chrome-launcher": "~3.2.0", 54 | "karma-coverage": "~2.2.0", 55 | "karma-jasmine": "~5.1.0", 56 | "karma-jasmine-html-reporter": "~2.1.0", 57 | "typescript": "~5.4.2" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxFilesModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import javax.annotation.Generated; 12 | 13 | import com.fasterxml.jackson.annotation.JsonCreator; 14 | import com.fasterxml.jackson.annotation.JsonProperty; 15 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 16 | import com.fasterxml.jackson.annotation.JsonValue; 17 | 18 | import lombok.AllArgsConstructor; 19 | import lombok.Getter; 20 | import lombok.NoArgsConstructor; 21 | import lombok.Setter; 22 | 23 | @Getter 24 | @Setter 25 | @AllArgsConstructor 26 | @NoArgsConstructor 27 | public class SpdxFilesModel { 28 | private String SPDXID; 29 | private List annotations; 30 | private List attributionTexts; 31 | private List checksums; 32 | private String comment; 33 | private String copyrightText; 34 | private List fileContributors; 35 | private List fileDependencies; 36 | private String fileName; 37 | private List fileTypes; 38 | private String licenseComments; 39 | private String licenseConcluded; 40 | private List licenseInfoInFiles; 41 | private String noticeText; 42 | 43 | 44 | public enum FileType { 45 | OTHER("OTHER"), 46 | DOCUMENTATION("DOCUMENTATION"), 47 | IMAGE("IMAGE"), 48 | VIDEO("VIDEO"), 49 | ARCHIVE("ARCHIVE"), 50 | SPDX("SPDX"), 51 | APPLICATION("APPLICATION"), 52 | SOURCE("SOURCE"), 53 | BINARY("BINARY"), 54 | TEXT("TEXT"), 55 | AUDIO("AUDIO"); 56 | private final String value; 57 | private final static Map CONSTANTS = new HashMap(); 58 | 59 | static { 60 | for (FileType c: values()) { 61 | CONSTANTS.put(c.value, c); 62 | } 63 | } 64 | 65 | FileType(String value) { 66 | this.value = value; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxInputModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | 8 | import java.util.List; 9 | 10 | import com.fasterxml.jackson.annotation.JsonProperty; 11 | 12 | import lombok.AllArgsConstructor; 13 | import lombok.Getter; 14 | import lombok.NoArgsConstructor; 15 | import lombok.Setter; 16 | 17 | @Getter 18 | @Setter 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | public class SpdxInputModel { 22 | @JsonProperty("SPDXID") 23 | private String SPDXID; 24 | private String spdxVersion; 25 | private String dataLicense; 26 | private String name; 27 | private String documentNamespace; 28 | private String documentDescribes; 29 | private SpdxCreationInfoModel creationInfo; 30 | private List annotations; 31 | private List externalDocumentRefs; 32 | private List hasExtractedLicensingInfos; 33 | private List revieweds; 34 | private List packages; 35 | private List files; 36 | private List relationships; 37 | private List snippets; 38 | 39 | public String getspdxVersion() { 40 | return spdxVersion; 41 | } 42 | 43 | public void setspdxVersion(String spdxVersion) { 44 | this.spdxVersion = spdxVersion; 45 | } 46 | 47 | public void setSPDXID(String SPDXID) { 48 | this.SPDXID = SPDXID; 49 | } 50 | 51 | public void setdataLicense(String dataLicense) { 52 | this.dataLicense = dataLicense; 53 | 54 | } 55 | 56 | public void setdocumentNameSpace(String documentNameSpace) { 57 | this.documentNamespace = documentNameSpace; 58 | 59 | } 60 | 61 | public void setname(String name) { 62 | this.name = name; 63 | 64 | } 65 | 66 | 67 | public void setcreationInfo(SpdxCreationInfoModel creationInfo) { 68 | this.creationInfo = creationInfo; 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/header/header.component.ts: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | // SPDX-License-Identifier: MIT 4 | import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; 5 | import { Router } from '@angular/router'; 6 | import jsPDF from 'jspdf'; 7 | import autoTable from 'jspdf-autotable'; 8 | import { RestEndpointsService } from '../services/rest-endpoints.service'; 9 | 10 | @Component({ 11 | selector: 'app-header', 12 | templateUrl: './header.component.html', 13 | styleUrls: ['./header.component.css'] 14 | }) 15 | export class HeaderComponent implements OnInit { 16 | 17 | sticky = true; 18 | constructor(private router: Router, 19 | public restEndPointService:RestEndpointsService) { 20 | 21 | } 22 | alertModal!: TemplateRef | null; 23 | isDialogBoxOpen = false; 24 | 25 | @ViewChild('noLogsModal') 26 | noLogsModal!: TemplateRef; 27 | 28 | ngOnInit(): void { 29 | 30 | } 31 | 32 | ngAfterViewInit() { 33 | 34 | } 35 | 36 | downloadUserManual() { 37 | const url = this.restEndPointService.downloadUserManual; // Replace with your actual URL 38 | window.open(url, '_blank'); 39 | } 40 | 41 | downloadAuditLog() { 42 | var auditLog = sessionStorage.getItem('log'); 43 | if (auditLog !== null) { 44 | const auditLogPdf = new jsPDF("l", "cm", "a3"); 45 | 46 | var head = [ 47 | { title: "Action", dataKey: "action" }, 48 | { title: "File Name", dataKey: "fileName" }, 49 | { title: "File Hash", dataKey: "fileHash" }, 50 | { title: "Timestamp", dataKey: "timestamp" } 51 | ]; 52 | 53 | autoTable(auditLogPdf, { 54 | columns: head, 55 | body: JSON.parse(auditLog) 56 | }) 57 | auditLogPdf.save('auditLog.pdf'); 58 | } else { 59 | this.openDialogBox(this.noLogsModal); 60 | 61 | } 62 | } 63 | 64 | openDialogBox(modalName: TemplateRef) { 65 | this.isDialogBoxOpen = true; 66 | this.alertModal = modalName; 67 | } 68 | 69 | closeDialogBox(){ 70 | this.isDialogBoxOpen = false; 71 | this.alertModal = null; 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/SbomUtilsServiceAppConfig.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils; 6 | 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 10 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 11 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 12 | 13 | import com.fasterxml.jackson.databind.DeserializationFeature; 14 | import com.fasterxml.jackson.databind.MapperFeature; 15 | import com.fasterxml.jackson.databind.ObjectMapper; 16 | 17 | import springfox.documentation.builders.PathSelectors; 18 | import springfox.documentation.builders.RequestHandlerSelectors; 19 | import springfox.documentation.spi.DocumentationType; 20 | import springfox.documentation.spring.web.plugins.Docket; 21 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 22 | 23 | @Configuration 24 | @EnableSwagger2 25 | public class SbomUtilsServiceAppConfig { 26 | 27 | 28 | @Bean 29 | public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 30 | return new PropertySourcesPlaceholderConfigurer(); 31 | } 32 | 33 | @Bean 34 | public ObjectMapper objectMapper() { 35 | ObjectMapper mapper = new ObjectMapper(); 36 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 37 | mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true); 38 | 39 | return mapper; 40 | } 41 | 42 | @Bean 43 | public Docket api() { 44 | return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.basePackage("com.sepia.sbomutils.controller")) 45 | .paths(PathSelectors.any()).build(); 46 | } 47 | 48 | @Bean 49 | public WebMvcConfigurer corsConfigurer() { 50 | return new WebMvcConfigurer() { 51 | @Override 52 | public void addCorsMappings(CorsRegistry registry) { 53 | registry.addMapping("/**"); 54 | } 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxCrossRefModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import com.fasterxml.jackson.annotation.JsonInclude; 8 | import com.fasterxml.jackson.annotation.JsonProperty; 9 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 10 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 11 | 12 | import lombok.AllArgsConstructor; 13 | import lombok.Getter; 14 | import lombok.NoArgsConstructor; 15 | import lombok.Setter; 16 | 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class SpdxCrossRefModel { 23 | 24 | @JsonInclude(JsonInclude.Include.NON_NULL) 25 | @JsonPropertyOrder({ 26 | "isLive", 27 | "isValid", 28 | "isWayBackLink", 29 | "match", 30 | "order", 31 | "timestamp", 32 | "url" 33 | }) 34 | 35 | @JsonProperty("isLive") 36 | @JsonPropertyDescription("Indicate a URL is still a live accessible location on the public internet") 37 | private String isLive; 38 | /** 39 | * True if the URL is a valid well formed URL 40 | * 41 | */ 42 | @JsonProperty("isValid") 43 | @JsonPropertyDescription("True if the URL is a valid well formed URL") 44 | private String isValid; 45 | /** 46 | * True if the License SeeAlso URL points to a Wayback archive 47 | * 48 | */ 49 | @JsonProperty("isWayBackLink") 50 | @JsonPropertyDescription("True if the License SeeAlso URL points to a Wayback archive") 51 | private String isWayBackLink; 52 | /** 53 | * Status of a License List SeeAlso URL reference if it refers to a website that matches the license text. 54 | * 55 | */ 56 | @JsonProperty("match") 57 | @JsonPropertyDescription("Status of a License List SeeAlso URL reference if it refers to a website that matches the license text.") 58 | private String match; 59 | /** 60 | * The ordinal order of this element within a list 61 | * 62 | */ 63 | @JsonProperty("order") 64 | @JsonPropertyDescription("The ordinal order of this element within a list") 65 | private Integer order; 66 | /** 67 | * Timestamp 68 | * 69 | */ 70 | @JsonProperty("timestamp") 71 | @JsonPropertyDescription("Timestamp") 72 | private String timestamp; 73 | /** 74 | * URL Reference 75 | * 76 | */ 77 | @JsonProperty("url") 78 | @JsonPropertyDescription("URL Reference") 79 | private String url; 80 | 81 | /** 82 | * Indicate a URL is still a live accessible location on the public internet 83 | * 84 | */ 85 | 86 | 87 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxPackageInfoModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import com.fasterxml.jackson.annotation.JsonProperty; 12 | 13 | import lombok.AllArgsConstructor; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | import lombok.Setter; 17 | 18 | 19 | @Getter 20 | @Setter 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | 24 | public class SpdxPackageInfoModel { 25 | @JsonProperty("SPDXID") 26 | private String SPDXID; 27 | private List annotations; 28 | private List attributionTexts; 29 | private String builtDate; 30 | private List checksums; 31 | private String comment; 32 | private String copyrightText; 33 | private String description; 34 | private String name; 35 | private String versionInfo; 36 | private String originator; 37 | private String supplier; 38 | private String downloadLocation; 39 | private List externalRefs; 40 | private Boolean filesAnalyzed; 41 | private String licenseConcluded; 42 | private String licenseDeclared; 43 | private List hasFiles; 44 | private String homepage; 45 | private String licenseComments; 46 | private List licenseInfoFromFiles; 47 | private String packageFileName; 48 | private SpdxPackageVerificationCodeModel packageVerificationCode; 49 | private PrimaryPackagePurpose primaryPackagePurpose; 50 | private String releaseDate; 51 | private String sourceInfo; 52 | private String summary; 53 | private String validUntilDate; 54 | 55 | 56 | public enum PrimaryPackagePurpose { 57 | 58 | OTHER("OTHER"), 59 | INSTALL("INSTALL"), 60 | ARCHIVE("ARCHIVE"), 61 | FIRMWARE("FIRMWARE"), 62 | APPLICATION("APPLICATION"), 63 | FRAMEWORK("FRAMEWORK"), 64 | LIBRARY("LIBRARY"), 65 | CONTAINER("CONTAINER"), 66 | SOURCE("SOURCE"), 67 | DEVICE("DEVICE"), 68 | OPERATING_SYSTEM("OPERATING_SYSTEM"), 69 | FILE("FILE"); 70 | 71 | private final String value; 72 | private final static Map CONSTANTS = new HashMap(); 73 | 74 | static { 75 | for (PrimaryPackagePurpose c: values()) { 76 | CONSTANTS.put(c.value, c); 77 | } 78 | } 79 | 80 | PrimaryPackagePurpose(String value) { 81 | this.value = value; 82 | } 83 | } 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | version = 1 6 | 7 | [[annotations]] 8 | path = "**/pom.xml" 9 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 10 | SPDX-License-Identifier = "MIT" 11 | 12 | [[annotations]] 13 | path = "DCO.txt" 14 | SPDx-FileCopyrightText = "Copyright (C) 2004, 2006 The Linux Foundation and its contributors." 15 | SPDX-License-Identifier = "LicenseRef-scancode-dco-1.1" 16 | 17 | [[annotations]] 18 | path = "Images/**" 19 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 20 | SPDX-License-Identifier = "CC-BY-4.0" 21 | 22 | [[annotations]] 23 | path = "Presentations/**" 24 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 25 | SPDX-License-Identifier = "CC-BY-4.0" 26 | 27 | [[annotations]] 28 | path = "Schema/**" 29 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 30 | SPDX-License-Identifier = "MIT" 31 | 32 | [[annotations]] 33 | path = "Tools/sbom-public-ui/*.json" 34 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 35 | SPDX-License-Identifier = "MIT" 36 | 37 | [[annotations]] 38 | path = "Tools/sbom-public-ui/.npmrc" 39 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 40 | SPDX-License-Identifier = "MIT" 41 | 42 | [[annotations]] 43 | path = "Tools/sbom-public-ui/src/favicon.ico" 44 | SPDX-FileCopyrightText = "Copyright (c) 2010-2025 Google LLC. https://angular.dev/license" 45 | SPDX-License-Identifier = "MIT" 46 | 47 | [[annotations]] 48 | path = "Tools/sbom-public-service/.settings/*" 49 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 50 | SPDX-License-Identifier = "MIT" 51 | 52 | [[annotations]] 53 | path = "Tools/sbom-public-service/images/media/*" 54 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 55 | SPDX-License-Identifier = "CC-BY-4.0" 56 | 57 | [[annotations]] 58 | path = "Tools/sbom-public-service/src/main/resources/*" 59 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 60 | SPDX-License-Identifier = "MIT" 61 | 62 | [[annotations]] 63 | path = "Tools/sbom-public-service/mvnw" 64 | SPDX-FileCopyrightText = "Copyright 2013-2022 The Apache Software Foundation" 65 | SPDX-License-Identifier = "Apache-2.0" 66 | 67 | [[annotations]] 68 | path = "Tools/sbom-public-service/mvnw.cmd" 69 | SPDX-FileCopyrightText = "Copyright 2013-2022 The Apache Software Foundation" 70 | SPDX-License-Identifier = "Apache-2.0" 71 | 72 | [[annotations]] 73 | path = "**/.project" 74 | SPDX-FileCopyrightText = "Copyright (C) 2025 Contributors to SEPIA" 75 | SPDX-License-Identifier = "MIT" 76 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxHasExtractedLicensingInfoModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import com.fasterxml.jackson.annotation.JsonProperty; 10 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 11 | 12 | import lombok.AllArgsConstructor; 13 | import lombok.Getter; 14 | import lombok.NoArgsConstructor; 15 | import lombok.Setter; 16 | 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class SpdxHasExtractedLicensingInfoModel { 23 | @JsonProperty("comment") 24 | private String comment; 25 | /** 26 | * Cross Reference Detail for a license SeeAlso URL 27 | * 28 | */ 29 | @JsonProperty("crossRefs") 30 | @JsonPropertyDescription("Cross Reference Detail for a license SeeAlso URL") 31 | private List crossRefs; 32 | /** 33 | * Provide a copy of the actual text of the license reference extracted from the package, file or snippet that is associated with the License Identifier to aid in future analysis. 34 | * 35 | */ 36 | @JsonProperty("extractedText") 37 | @JsonPropertyDescription("Provide a copy of the actual text of the license reference extracted from the package, file or snippet that is associated with the License Identifier to aid in future analysis.") 38 | private String extractedText; 39 | /** 40 | * A human readable short form license identifier for a license. The license ID is either on the standard license list or the form "LicenseRef-[idString]" where [idString] is a unique string containing letters, numbers, "." or "-". When used within a license expression, the license ID can optionally include a reference to an external document in the form "DocumentRef-[docrefIdString]:LicenseRef-[idString]" where docRefIdString is an ID for an external document reference. 41 | * 42 | */ 43 | @JsonProperty("licenseId") 44 | @JsonPropertyDescription("A human readable short form license identifier for a license. The license ID is either on the standard license list or the form \"LicenseRef-[idString]\" where [idString] is a unique string containing letters, numbers, \".\" or \"-\". When used within a license expression, the license ID can optionally include a reference to an external document in the form \"DocumentRef-[docrefIdString]:LicenseRef-[idString]\" where docRefIdString is an ID for an external document reference.") 45 | private String licenseId; 46 | /** 47 | * Identify name of this SpdxElement. 48 | * 49 | */ 50 | @JsonProperty("name") 51 | @JsonPropertyDescription("Identify name of this SpdxElement.") 52 | private String name; 53 | @JsonProperty("seeAlsos") 54 | private List seeAlsos; 55 | } -------------------------------------------------------------------------------- /Presentations/20240912_BFOSS24/README.md: -------------------------------------------------------------------------------- 1 | # SEPIA – SBOM Exchange Procedures, Interfaces and Architecture 2 | 3 | * Presenter: Hans-Malte Kern, Robert Bosch GmbH 4 | * Date: 2024-09-12 5 | * Language: EN 6 | * Event: BitKom Open Source Forum 2024 (bfoss24) 7 | * Location: Erfurt, Germany 8 | * Link: https://www.bitkom.org/bfoss24 9 | 10 | ## Teaser English (on the fly translation) 11 | 12 | With OpenChain we have an international standard (ISO/IEC 5230) on the most 13 | important requirements for an open source license compliance program. 14 | SPDX and Cyclone DX each define their own format for exchanging information 15 | on software components. However, both formats are not clear enough and allow 16 | the same information to be documented in different ways. 17 | 18 | Robert Bosch occupies different positions in the value chain - Tier 0, 19 | Tier 1 to Tier X - or in other words: original creator of a software, 20 | integrator, refiner and supplier, marketer. And here we notice that the 21 | definition of the formats is not sufficient. Even with internal value chains, 22 | due to the different views of SPDX and CycloneDX, we always have a break in 23 | content or format and therefore a tool break, which makes complete automation 24 | almost impossible. 25 | 26 | We see a variety of different requirements from external customers in the 27 | automotive sector regarding the exchange format and their own solutions, 28 | some of which are based on existing standards. Additional requirements such 29 | as the EU Cyber Resilience Act (CRA) or BSI TR-3183 must be taken into 30 | account in an SBOM. 31 | 32 | At Bosch, we have started to define a set of meta information that must be 33 | exchanged when software components are shared internally. This meta 34 | information can be displayed in both SPDX and CycloneDX and the data types 35 | of the individual elements are automatically checked using a schema. This 36 | allows us to automatically determine whether we can further process an SBOM 37 | automatically. We are currently planning to make this schema available to our 38 | suppliers in order to increase the quality of the SBOMs supplied. 39 | 40 | In order to be able to use SBOMs more effectively and, above all, more 41 | efficiently along the value chain, we need more such schemes, e.g. one for 42 | the automotive sector. And I would like to use the presentation for this: 43 | to define an initiative for the standardization of SBOM and the development 44 | of uniform validation schemes for individual industrial sectors. I would 45 | like to start in the automotive sector, as the automotive industry is a key 46 | industry for Germany and the multitude of formats with mandatory fields from 47 | individual automotive manufacturers has progressed so far that reusing 48 | meta-information is extremely difficult. 49 | 50 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/service/SbomUtilityService.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | package com.sepia.sbomutils.service; 5 | 6 | import java.security.NoSuchAlgorithmException; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import com.sepia.sbomutils.model.BomFilesInputModel; 13 | import com.sepia.sbomutils.model.ChangeLog; 14 | 15 | public interface SbomUtilityService { 16 | 17 | 18 | 19 | /** 20 | * 21 | * @param inputFile 22 | * @param sbomInputModel 23 | * @return true if input is uploaded successfully and false otherwise 24 | */ 25 | BomFilesInputModel uploadInputFile(Optional inputFile, BomFilesInputModel sbomInputModel, boolean isFromApi); 26 | 27 | /** 28 | * 29 | * @param sbomInputModel 30 | * @return 31 | */ 32 | BomFilesInputModel deleteSbomEntry(BomFilesInputModel sbomInputModel); 33 | 34 | /** 35 | * 36 | * @param timestamp 37 | * @return list of uploaded files and corresponding details 38 | */ 39 | List getUploadedFiles(String timestamp); 40 | 41 | /** 42 | * 43 | * @param sbomInputModel 44 | * @return 45 | */ 46 | BomFilesInputModel validateSboms(BomFilesInputModel sbomInputModel, boolean isMerge, boolean isReplace); 47 | 48 | /** 49 | * 50 | * @param bomFilesInputModel 51 | * @return 52 | */ 53 | BomFilesInputModel fetchErrorDetails(BomFilesInputModel bomFilesInputModel); 54 | 55 | /** 56 | * 57 | * @param sbomInputModel 58 | * @return 59 | */ 60 | BomFilesInputModel fetchJsonContent(BomFilesInputModel sbomInputModel); 61 | 62 | /** 63 | * 64 | * @param bomInputList 65 | * @param bomMetadata 66 | * @return 67 | */ 68 | BomFilesInputModel mergeSboms(List bomInputList, String bomMetadata, String schemaType, boolean isFromApp); 69 | 70 | /** 71 | * 72 | * @param sbomInputModel 73 | */ 74 | void clearSession(BomFilesInputModel sbomInputModel); 75 | 76 | /** 77 | * 78 | * @param sbomInputModel 79 | * @return saved bom files input model 80 | */ 81 | BomFilesInputModel replaceFile(BomFilesInputModel sbomInputModel); 82 | 83 | /** 84 | * 85 | * @param mergedValue 86 | * @param initialValue 87 | * @return 88 | */ 89 | List getJsonDifferences(String currentValue,BomFilesInputModel sbomInputModel,Boolean isMerge); 90 | 91 | /** 92 | * 93 | * @param currentValue 94 | * @param bomFilesInputModel 95 | * @return 96 | * @throws NoSuchAlgorithmException 97 | */ 98 | BomFilesInputModel prepareForDownload(String currentValue, BomFilesInputModel bomFilesInputModel) throws NoSuchAlgorithmException; 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/CycloneDXComponentModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.List; 8 | 9 | import com.fasterxml.jackson.annotation.JsonProperty; 10 | import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; 11 | import com.google.gson.annotations.SerializedName; 12 | 13 | import lombok.AllArgsConstructor; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | import lombok.Setter; 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class CycloneDXComponentModel { 23 | 24 | public enum Type { 25 | @JsonProperty("application") 26 | APPLICATION("application"), 27 | @JsonProperty("framework") 28 | FRAMEWORK("framework"), 29 | @JsonProperty("library") 30 | LIBRARY("library"), 31 | @JsonProperty("container") 32 | CONTAINER("container"), 33 | @JsonProperty("operating-system") 34 | OPERATING_SYSTEM("operating-system"), 35 | @JsonProperty("device") 36 | DEVICE("device"), 37 | @JsonProperty("firmware") 38 | FIRMWARE("firmware"), 39 | @JsonProperty("file") 40 | FILE("file"); 41 | 42 | private final String name; 43 | 44 | public String getTypeName() { 45 | return this.name; 46 | } 47 | 48 | Type(String name) { 49 | this.name = name; 50 | } 51 | } 52 | 53 | public enum Scope { 54 | @JsonProperty("required") 55 | REQUIRED("required"), 56 | @JsonProperty("optional") 57 | OPTIONAL("optional"), 58 | @JsonProperty("excluded") 59 | EXCLUDED("excluded"); 60 | 61 | private final String name; 62 | 63 | public String getScopeName() { 64 | return this.name; 65 | } 66 | 67 | Scope(String name) { 68 | this.name = name; 69 | } 70 | } 71 | 72 | private Type type; 73 | @JacksonXmlProperty(isAttribute = true, localName = "bom-ref") 74 | @JsonProperty("bom-ref") 75 | @SerializedName("bom-ref") 76 | private String bomRef; 77 | @JacksonXmlProperty(isAttribute = true, localName = "mime-type") 78 | @JsonProperty("mime-type") 79 | private String mimeType; 80 | private String group; 81 | private String name; 82 | private String version; 83 | private String description; 84 | private List hashes; 85 | private List licenses; 86 | private String copyright; 87 | private String cpe; 88 | private String purl; 89 | private List externalReferences; 90 | private CycloneDXOrganizationalEntityModel supplier; 91 | private List properties; 92 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxRelationshipModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import javax.annotation.Generated; 11 | 12 | 13 | import lombok.AllArgsConstructor; 14 | import lombok.Getter; 15 | import lombok.NoArgsConstructor; 16 | import lombok.Setter; 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class SpdxRelationshipModel { 23 | private String spdxElementId; 24 | private String comment; 25 | private String relatedSpdxElement; 26 | private RelationshipType relationshipType; 27 | 28 | @Generated("jsonschema2pojo") 29 | public enum RelationshipType { 30 | 31 | VARIANT_OF("VARIANT_OF"), 32 | COPY_OF("COPY_OF"), 33 | PATCH_FOR("PATCH_FOR"), 34 | TEST_DEPENDENCY_OF("TEST_DEPENDENCY_OF"), 35 | CONTAINED_BY("CONTAINED_BY"), 36 | DATA_FILE_OF("DATA_FILE_OF"), 37 | OPTIONAL_COMPONENT_OF("OPTIONAL_COMPONENT_OF"), 38 | ANCESTOR_OF("ANCESTOR_OF"), 39 | GENERATES("GENERATES"), 40 | CONTAINS("CONTAINS"), 41 | OPTIONAL_DEPENDENCY_OF("OPTIONAL_DEPENDENCY_OF"), 42 | FILE_ADDED("FILE_ADDED"), 43 | REQUIREMENT_DESCRIPTION_FOR("REQUIREMENT_DESCRIPTION_FOR"), 44 | DEV_DEPENDENCY_OF("DEV_DEPENDENCY_OF"), 45 | DEPENDENCY_OF("DEPENDENCY_OF"), 46 | BUILD_DEPENDENCY_OF("BUILD_DEPENDENCY_OF"), 47 | DESCRIBES("DESCRIBES"), 48 | PREREQUISITE_FOR("PREREQUISITE_FOR"), 49 | HAS_PREREQUISITE("HAS_PREREQUISITE"), 50 | PROVIDED_DEPENDENCY_OF("PROVIDED_DEPENDENCY_OF"), 51 | DYNAMIC_LINK("DYNAMIC_LINK"), 52 | DESCRIBED_BY("DESCRIBED_BY"), 53 | METAFILE_OF("METAFILE_OF"), 54 | DEPENDENCY_MANIFEST_OF("DEPENDENCY_MANIFEST_OF"), 55 | PATCH_APPLIED("PATCH_APPLIED"), 56 | RUNTIME_DEPENDENCY_OF("RUNTIME_DEPENDENCY_OF"), 57 | TEST_OF("TEST_OF"), 58 | TEST_TOOL_OF("TEST_TOOL_OF"), 59 | DEPENDS_ON("DEPENDS_ON"), 60 | SPECIFICATION_FOR("SPECIFICATION_FOR"), 61 | FILE_MODIFIED("FILE_MODIFIED"), 62 | DISTRIBUTION_ARTIFACT("DISTRIBUTION_ARTIFACT"), 63 | AMENDS("AMENDS"), 64 | DOCUMENTATION_OF("DOCUMENTATION_OF"), 65 | GENERATED_FROM("GENERATED_FROM"), 66 | STATIC_LINK("STATIC_LINK"), 67 | OTHER("OTHER"), 68 | BUILD_TOOL_OF("BUILD_TOOL_OF"), 69 | TEST_CASE_OF("TEST_CASE_OF"), 70 | PACKAGE_OF("PACKAGE_OF"), 71 | DESCENDANT_OF("DESCENDANT_OF"), 72 | FILE_DELETED("FILE_DELETED"), 73 | EXPANDED_FROM_ARCHIVE("EXPANDED_FROM_ARCHIVE"), 74 | DEV_TOOL_OF("DEV_TOOL_OF"), 75 | EXAMPLE_OF("EXAMPLE_OF"); 76 | private final String value; 77 | private final static Map CONSTANTS = new HashMap(); 78 | 79 | static { 80 | for (RelationshipType c: values()) { 81 | CONSTANTS.put(c.value, c); 82 | } 83 | } 84 | 85 | RelationshipType(String value) { 86 | this.value = value; 87 | } 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /Installation.md: -------------------------------------------------------------------------------- 1 | 4 | # Installation Guide 5 | 6 | This guide will help you set up both the SBOM Public UI (frontend) and the SbomPublic Backend Service. Please follow the steps below. 7 | 8 | --- 9 | 10 | ## Prerequisites 11 | 12 | Before you begin, ensure you have the following installed on your system: 13 | 14 | - **Java 1.8** 15 | - **Apache Maven 3.8.6** 16 | - **Spring Boot 2.3.8** 17 | - **Eclipse IDE** (or any preferred Java IDE) 18 | - **Node.js** (version 14.x or higher recommended) - [Download Node.js](https://nodejs.org/) 19 | - **npm** (comes with Node.js) - [Learn more](https://www.npmjs.com/) 20 | - **Angular CLI** (recommended) 21 | Install globally using: 22 | ```bash 23 | npm install -g @angular/cli 24 | ``` 25 | - **Visual Studio Code** (or any preferred code editor) 26 | - **Operating System:** Windows 10/11 (win32 x64) 27 | 28 | --- 29 | 30 | ## 1. Setting Up SBOM Public UI (Frontend) 31 | 32 | Follow these steps to set up and run the frontend application: 33 | 34 | 1. **Clone the repository:** 35 | ```bash 36 | git clone https:// 37 | ``` 38 | 39 | 2. **Install dependencies:** 40 | Open the downloaded source code(sbom-public-ui) using Visual Studio Code and then install the dependencies using 41 | ```bash 42 | npm install 43 | ``` 44 | 45 | 3. **Run the development server:** 46 | ```bash 47 | ng serve 48 | ``` 49 | The app will be available at [http://localhost:4200/](http://localhost:4200/) by default. 50 | 51 | 4. **For production build:** 52 | ```bash 53 | ng build --prod 54 | ``` 55 | After the build completion deployable build source available inside dist directory.Move the build to your server 56 | --- 57 | 58 | ## 2. Setting Up SbomPublic Backend Service 59 | 60 | Follow these steps to set up and run the backend service: 61 | 62 | 1. **Clone the repository:** 63 | ```bash 64 | git clone https:// 65 | ``` 66 | 67 | 2. **Build the project using Maven:** 68 | Open the downloaded source code(sbom-public-service) using Eclipse IDE(or any preferred Java IDE) and then install the dependencies using 69 | ```bash 70 | mvn clean install 71 | ``` 72 | Inside the application.properties change the following properties 73 | sbom.upload.path=(Eg:c:\\temp\\sbom\\) 74 | 75 | 3. **Run the application:** 76 | ```bash 77 | mvn spring-boot:run 78 | ``` 79 | 4. **For production build:** 80 | to run the packaged JAR file: 81 | ```bash 82 | java -jar target/sbom-public-*.jar 83 | ``` 84 | After the build completion deployable build source available inside target directory. Move the build to your server 85 | 86 | --- 87 | 88 | You are now ready to use both the frontend and backend services. If you encounter any issues, please refer to the project documentation or contact the maintainers. -------------------------------------------------------------------------------- /Presentations/20240912_BFOSS24/README_de.md: -------------------------------------------------------------------------------- 1 | # SEPIA – SBOM Exchange Procedures, Interfaces and Architecture 2 | 3 | * Presenter: Hans-Malte Kern, Robert Bosch GmbH 4 | * Date: 2024-09-12 5 | * Language: EN 6 | * Event: BitKom Open Source Forum 2024 (bfoss24) 7 | * Location: Erfurt, Germany 8 | * Link: https://www.bitkom.org/bfoss24 9 | 10 | 11 | ## Teaser Deutsch (Published in BitKom Open Source Forum Program 2024) 12 | 13 | Mit OpenChain haben wir einen internationalen Standard (ISO/IEC 5230) zu den wichtigsten Anforderungen an 14 | ein Open-Source-Lizenz-Compliance-Programm. SPDX und Cyclone DX definieren jeweils ein eigenes Format um 15 | Informationen zu Softwarekomponenten austauschen zu können. Beide Formate sind jedoch nicht eindeutig 16 | genug und erlauben die Dokumentation derselbe Information auf unterschiedliche Weisen. 17 | In der Wertschöpfungskette nimmt die Robert Bosch unterschiedliche Positionen ein – Tier-0, Tier-1 bis Tier-X – 18 | oder mit anderen Worten: Ur-Ersteller einer Software, Integrator, Veredler und Lieferant, In-Markt-Bringer. Und 19 | hier merken wir, dass die Festlegung der Formate nicht ausreichend sind. Selbst bei internen Wertschöpfungsket- 20 | ten haben wir Aufgrund der unterschiedlichen Sichten von SPDX und CycloneDX immer wieder einen Inhalts- bzw. 21 | Format- und daher einen Toolbruch, was eine vollständige Automatisierung nahezu unmöglich macht. 22 | Bei externen Kunden im Automobilbereich sehen wir eine Vielzahl von unterschiedlichen Anforderungen bzgl. des 23 | Austauschformats und eigenen Lösungen z.T. basierend auf den existierenden Standards. Zusätzliche Anforderun- 24 | gen wie z. B. des EU-Gesetz über Cyberresilienz (CRA) oder BSI TR-3183 müssen bei einer SBOM berücksichtigt 25 | werden. 26 | 27 | Bei Bosch haben wir angefangen einen Satz an Meta-Informationen zu definieren, die bei der internen Weiterga- 28 | be von Softwarekomponenten ausgetauscht werden müssen. Diese Meta-Informationen lassen sich sowohl in 29 | SPDX als auch CycloneDX darstellen und die Datentypen der einzelnen Elemente werden automatisch über ein 30 | Schema geprüft. Somit können wir automatisch feststellen ob eine SBOM von uns automatisiert weiterbearbeitet 31 | werden kann. Momentan planen wir diese Schema auch unseren Lieferanten zur Verfügung zu stellen, um die 32 | Qualität der zugelieferten SBOMs zu erhöhen. 33 | 34 | Um SBOMs effektiver und vor allem effizienter entlang der Wertschöpfungskette nutzen zu können brauchen wir 35 | mehr solcher Schemes, z. B. eins für den Automobilbereich. Und hierfür würde ich gerne die Präsentation nutzen: 36 | eine Initiative für die Standardisierung von SBOM und die Entwicklung von einheitlichen Validierungs-Schemas für 37 | einzelne Industriebereiche zu definieren. Anfangen würde ich gerne im Automobilbereich, da die Automobilindus- 38 | trie für Deutschland eine Schlüsselindustrie ist und die Vielzahl von Formaten mit Pflichtfeldern der einzelnen 39 | Automobilhersteller so weit vorangeschritten ist, dass eine Wiederverwendung von Meta-Informationen extrem 40 | schwer fällt. 41 | 42 | -------------------------------------------------------------------------------- /Schema/CycloneDX/Bosch_SEPIA/bosch_sepia_cyclonedx_1.4.md: -------------------------------------------------------------------------------- 1 | ## CycloneDX_1.4 2 | 3 | | Root Element | Child Element | | | | 4 | |:-------------|:--------------|:-------------------|:----------|:----------| 5 | | | | | | | 6 | | bomFormat | | | | | 7 | | specVersion | | | | | 8 | | serialNumber | | | | | 9 | | version | | | | | 10 | | metadata | timestamp | | | | 11 | | | supplier | name | | | 12 | | | | contact | email | | 13 | | | | | | | 14 | | | tools | vendor | | | 15 | | | | name | | | 16 | | | | version | | | 17 | | | | hashes | content | | 18 | | | | | alg | | 19 | | | | | | | 20 | | | | externalReferences | hashes | content | 21 | | | | | | alg | 22 | | | | | type | | 23 | | | | | comment | | 24 | | | | | url | | 25 | | | component | name | | | 26 | | | | version | | | 27 | | | | purl | | | 28 | | | | type | | | 29 | | | | | | | 30 | | | | | | | 31 | | | | | | | 32 | | | | | | | 33 | | | | | | | 34 | | | licenses | license/expression | id/name | | 35 | | | | | | | 36 | | | | | | | 37 | | components | name | | | | 38 | | | version | | | | 39 | | | type | | | | 40 | | | purl | | | | 41 | | | licenses | license/expression | id/name | | 42 | | | copyright | | | | 43 | 44 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/BomFilesInputModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 13 | import com.fasterxml.jackson.annotation.JsonInclude; 14 | import com.fasterxml.jackson.annotation.JsonInclude.Include; 15 | 16 | import io.swagger.annotations.ApiModelProperty; 17 | import lombok.AllArgsConstructor; 18 | import lombok.Getter; 19 | import lombok.NoArgsConstructor; 20 | import lombok.Setter; 21 | 22 | @Getter 23 | @Setter 24 | @AllArgsConstructor 25 | @NoArgsConstructor 26 | @JsonIgnoreProperties(ignoreUnknown = true) 27 | @JsonInclude(value = Include.NON_NULL) 28 | 29 | public class BomFilesInputModel { 30 | 31 | @ApiModelProperty(required = false) 32 | private String inputType; 33 | 34 | @ApiModelProperty(required = true) 35 | private String schemaType; 36 | 37 | @ApiModelProperty(required = true) 38 | private String schemaVersion; 39 | 40 | private MultipartFile sbomFile; 41 | 42 | private MultipartFile schemaFile; 43 | 44 | @ApiModelProperty(required = true) 45 | private boolean schema; 46 | 47 | @ApiModelProperty(required = true) 48 | private int index; 49 | 50 | @ApiModelProperty(required = true) 51 | private String timestamp; 52 | 53 | @ApiModelProperty(hidden = true) 54 | private String sbomJsonString; 55 | 56 | @ApiModelProperty(hidden = true) 57 | private String schemaJsonString; 58 | 59 | @ApiModelProperty(required = false) 60 | private boolean valid; 61 | private String filePath; 62 | 63 | @ApiModelProperty(hidden = true) 64 | private boolean validatedAlready; 65 | 66 | @ApiModelProperty(required = true) 67 | private String sbomFileName; 68 | 69 | @ApiModelProperty(required = false) 70 | private String schemaFileName; 71 | 72 | @ApiModelProperty(required = false) 73 | private List errorDetails = new ArrayList<>(); 74 | 75 | @ApiModelProperty(hidden = true) 76 | private String dirName; 77 | 78 | @ApiModelProperty(required = false) 79 | private List changeLogsList; 80 | 81 | @ApiModelProperty(required = false) 82 | private String fileHash; 83 | 84 | @ApiModelProperty(required = false) 85 | private List customErrorDetails; 86 | 87 | @ApiModelProperty(required = false) 88 | private Object sbomJson; 89 | 90 | @ApiModelProperty(required = false) 91 | private Object schemaJson; 92 | 93 | public void addErrorModel(List errorModel) { 94 | if (this.errorDetails == null) { 95 | this.errorDetails = new ArrayList<>(); 96 | } 97 | this.errorDetails.addAll(errorModel); 98 | } 99 | 100 | @ApiModelProperty(required = false) 101 | private String fossidServer; 102 | 103 | @ApiModelProperty(required = false) 104 | private String apiKey; 105 | 106 | @ApiModelProperty(required = false) 107 | private String scanCode; 108 | 109 | @ApiModelProperty(required = false) 110 | private String ntid; 111 | 112 | @ApiModelProperty(required = false) 113 | private String message; 114 | 115 | @ApiModelProperty(required = false) 116 | private Integer status; 117 | } -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/util/JsonPathFinder.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | package com.sepia.sbomutils.util; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.Iterator; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Map.Entry; 12 | import java.util.stream.Collectors; 13 | 14 | import org.json.JSONArray; 15 | import org.json.JSONObject; 16 | 17 | import com.fasterxml.jackson.databind.JsonNode; 18 | 19 | public class JsonPathFinder { 20 | 21 | private JsonPathFinder() { 22 | throw new AssertionError("Cannot instantiate JsonPathFinder"); 23 | } 24 | 25 | public static List findRepetitionPaths(JsonNode jsonNode, String key) { 26 | Map> valuePaths = new HashMap<>(); 27 | findRepititionsRecursive(jsonNode, key, "$", valuePaths); 28 | return valuePaths.entrySet().stream().filter(entry -> entry.getValue().size() > 1) 29 | .flatMap(entry -> entry.getValue().stream()).collect(Collectors.toList()); 30 | } 31 | 32 | private static void findRepititionsRecursive(JsonNode jsonNode, String key, String path, 33 | Map> valuePaths) { 34 | if (jsonNode.isObject()) { 35 | Iterator> fields = jsonNode.fields(); 36 | 37 | while (fields.hasNext()) { 38 | Entry field = fields.next(); 39 | String curPath = path + "." + field.getKey(); 40 | 41 | if (field.getKey().equals(key)) { 42 | valuePaths.computeIfAbsent(field.getValue().asText(), k -> new ArrayList<>()).add(curPath); 43 | } 44 | 45 | findRepititionsRecursive(field.getValue(), key, curPath, valuePaths); 46 | } 47 | } else if (jsonNode.isArray()) { 48 | for (int i = 0; i < jsonNode.size(); i++) { 49 | JsonNode arr = jsonNode.get(i); 50 | findRepititionsRecursive(arr, key, path + "[" + i + "]", valuePaths); 51 | } 52 | } 53 | } 54 | 55 | public static String getPath(JSONObject json, String key, String value, boolean isObj) { 56 | return recursiveSearch(json, key, value, "$", isObj); 57 | } 58 | 59 | private static String recursiveSearch(JSONObject obj, String key, String value, String path, boolean isObj) { 60 | if (obj.has(key) && obj.get(key).equals(value)) { 61 | return path + "." + key; 62 | } 63 | if (isObj && obj.similar(new JSONObject(value))) { 64 | return path + "." + key; 65 | } 66 | 67 | for (String k : obj.keySet()) { 68 | Object v = obj.get(k); 69 | if (v instanceof JSONObject) { 70 | String result = recursiveSearch((JSONObject) v, key, value, path.isEmpty() ? k : path + "." + k, isObj); 71 | if (result != null) { 72 | return result; 73 | } 74 | } else if (v instanceof JSONArray) { 75 | String result = recursiveSearch((JSONArray) v, key, value, path.isEmpty() ? k : path + "." + k, isObj); 76 | if (result != null) { 77 | return result; 78 | } 79 | } 80 | } 81 | return null; 82 | } 83 | 84 | private static String recursiveSearch(JSONArray arr, String key, String value, String path, boolean isObj) { 85 | 86 | for (int i = 0; i < arr.length(); i++) { 87 | Object v = arr.get(i); 88 | if (v instanceof JSONObject) { 89 | String result = recursiveSearch((JSONObject) v, key, value, path + "[" + i + "]", isObj); 90 | if (result != null) { 91 | return result; 92 | } 93 | } else if (v instanceof JSONArray) { 94 | String result = recursiveSearch((JSONArray) v, key, value, path + "[" + i + "]", isObj); 95 | if (result != null) { 96 | return result; 97 | } 98 | } 99 | } 100 | return null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "sbom-utils-ui": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:component": { 10 | "standalone": false 11 | }, 12 | "@schematics/angular:directive": { 13 | "standalone": false 14 | }, 15 | "@schematics/angular:pipe": { 16 | "standalone": false 17 | } 18 | }, 19 | "root": "", 20 | "sourceRoot": "src", 21 | "prefix": "app", 22 | "architect": { 23 | "build": { 24 | "builder": "@angular-devkit/build-angular:application", 25 | "options": { 26 | "outputPath": "dist/sbom-utils-ui", 27 | "index": "src/index.html", 28 | "browser": "src/main.ts", 29 | "polyfills": [ 30 | "zone.js" 31 | ], 32 | "tsConfig": "tsconfig.app.json", 33 | "assets": [ 34 | 35 | "src/favicon.ico", 36 | "src/assets" 37 | ], 38 | "styles": [ 39 | "node_modules/bootstrap/dist/css/bootstrap.min.css", 40 | "src/styles.scss", 41 | "node_modules/@ng-select/ng-select/themes/default.theme.css", 42 | "node_modules/@fortawesome/fontawesome-free/css/all.min.css" 43 | ], 44 | "scripts": [ 45 | "node_modules/jquery/dist/jquery.js", 46 | "node_modules/bootstrap/dist/js/bootstrap.js" 47 | ] 48 | }, 49 | "configurations": { 50 | "production": { 51 | "budgets": [ 52 | { 53 | "type": "initial", 54 | "maximumWarning": "3mb", 55 | "maximumError": "4mb" 56 | }, 57 | { 58 | "type": "anyComponentStyle", 59 | "maximumWarning": "3mb", 60 | "maximumError": "4mb" 61 | } 62 | ], 63 | "outputHashing": "all" 64 | }, 65 | "development": { 66 | "optimization": false, 67 | "extractLicenses": false, 68 | "sourceMap": true 69 | } 70 | }, 71 | "defaultConfiguration": "production" 72 | }, 73 | "serve": { 74 | "builder": "@angular-devkit/build-angular:dev-server", 75 | "configurations": { 76 | "production": { 77 | "buildTarget": "sbom-utils-ui:build:production" 78 | }, 79 | "development": { 80 | "buildTarget": "sbom-utils-ui:build:development" 81 | } 82 | }, 83 | "defaultConfiguration": "development" 84 | }, 85 | "extract-i18n": { 86 | "builder": "@angular-devkit/build-angular:extract-i18n", 87 | "options": { 88 | "buildTarget": "sbom-utils-ui:build" 89 | } 90 | }, 91 | "test": { 92 | "builder": "@angular-devkit/build-angular:karma", 93 | "options": { 94 | "polyfills": [ 95 | "zone.js", 96 | "zone.js/testing" 97 | ], 98 | "tsConfig": "tsconfig.spec.json", 99 | "assets": [ 100 | 101 | "src/favicon.ico", 102 | "src/assets" 103 | ], 104 | "styles": [ 105 | "src/styles.scss" 106 | ], 107 | "scripts": [] 108 | } 109 | } 110 | } 111 | } 112 | }, 113 | "cli": { 114 | "analytics": false 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/util/Constants.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | package com.sepia.sbomutils.util; 5 | 6 | public class Constants { 7 | 8 | private Constants() { 9 | throw new AssertionError("Cannot instantiate Constants class"); 10 | } 11 | 12 | public static final String JSON = "json"; 13 | public static final String OSPDX = "OSPDX"; 14 | public static final String OCYDX = "OCYDX"; 15 | public static final String JSN = "JSN"; 16 | public static final String ATTACHMENT_JSON = "attachment; filename=downloaded.json"; 17 | public static final String ATTACHMENT_XML = "attachment; filename=downloaded.xml"; 18 | 19 | public static final String SBOM_INPUT = "sbomInput"; 20 | public static final String OPT_UPLOAD_SBOM = "OptUploadBOM"; 21 | public static final String CUSTOM = "custom"; 22 | public static final String OPT_COMPAOSS = "OptCompaoss"; 23 | 24 | public static final String SPDX = "SPDX"; 25 | public static final String CYDX = "CYDX"; 26 | public static final String BTOCYDX = "BTOCYDX"; 27 | public static final String CYCLONEDX_LC = "cyclonedx"; 28 | public static final String SPDX_LC = "spdx"; 29 | public static final String SPDX2_2_LC = "spdx2.2"; 30 | 31 | public static final String CDX_14 = "cdx14"; 32 | public static final String SPDX_23 = "spdx23"; 33 | 34 | public static final String UTF_8 = "UTF-8"; 35 | public static final String UNDERSCORE = "_"; 36 | public static final String ZERO = "0"; 37 | 38 | public static final String DOLLAR_SCHEMA = "$schema"; 39 | public static final String TILDE_SCHEMA = "~schema"; 40 | public static final String ERROR_LOG_TXT = "error_log.txt"; 41 | public static final String SUCCESS_LOG_TXT = "success_log.txt"; 42 | public static final String ADD = "add"; 43 | public static final String REPLACE = "replace"; 44 | 45 | public static final String MERGED_FILE = "Merged File"; 46 | public static final String SCHEMA = "schema"; 47 | 48 | public static final String JSON_EXT = ".json"; 49 | 50 | public static final String PACKAGES = "packages"; 51 | public static final String ANNOTATIONS = "annotations"; 52 | public static final String EXTERNALDOCUMENTREFS = "externalDocumentRefs"; 53 | public static final String HAS_EXTRACTED_LICENSING_INFOS = "hasExtractedLicensingInfos"; 54 | public static final String FILES = "files"; 55 | public static final String SNIPPETS = "snippets"; 56 | public static final String RELATIONSHIPS = "relationships"; 57 | public static final String SPDXID = "SPDXID"; 58 | public static final String SPDX_VERSION = "spdxVersion"; 59 | public static final String DATALICENSE = "dataLicense"; 60 | public static final String DOCUMENT_NAMESPACE = "documentNamespace"; 61 | public static final String CREATION_INFO = "creationInfo"; 62 | public static final String NAME = "name"; 63 | public static final String VERSION_INFO = "versionInfo"; 64 | public static final String SPDX_ELEMENT_ID = "spdxElementId"; 65 | public static final String RELATIONSHIP_TYPE = "relationshipType"; 66 | public static final String RELATED_SPDX_ELEMENT = "relatedSpdxElement"; 67 | public static final String RANGES = "ranges"; 68 | public static final String END_POINTER = "endPointer"; 69 | public static final String REFERENCE = "reference"; 70 | public static final String START_POINTER = "startPointer"; 71 | public static final String FILE_NAME = "FileName"; 72 | public static final String SNIPPET_FROM_FILE = "snippetFromFile"; 73 | public static final String DESCRIBES = "DESCRIBES"; 74 | public static final String CONTAINS = "CONTAINS"; 75 | public static final String DUPLICATE_SPDXID = "Duplicate SPDXID"; 76 | public static final String ORGANIZATION = "Organization: "; 77 | public static final String UNKNOWN = "[UNKNOWN]"; 78 | public static final String RDFXML = "rdf.xml"; 79 | public static final String SYMBOLS = "^\"|\"$"; 80 | } 81 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/model/SpdxPackageChecksumsModel.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | 5 | package com.sepia.sbomutils.model; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import javax.annotation.Generated; 11 | 12 | import com.fasterxml.jackson.annotation.JsonCreator; 13 | import com.fasterxml.jackson.annotation.JsonProperty; 14 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 15 | import com.fasterxml.jackson.annotation.JsonValue; 16 | 17 | import lombok.AllArgsConstructor; 18 | import lombok.Getter; 19 | import lombok.NoArgsConstructor; 20 | import lombok.Setter; 21 | 22 | @Getter 23 | @Setter 24 | @AllArgsConstructor 25 | @NoArgsConstructor 26 | public class SpdxPackageChecksumsModel { 27 | 28 | 29 | /** 30 | * Identifies the algorithm used to produce the subject Checksum. Currently, SHA-1 is the only supported algorithm. It is anticipated that other algorithms will be supported at a later time. 31 | * 32 | */ 33 | @JsonProperty("algorithm") 34 | @JsonPropertyDescription("Identifies the algorithm used to produce the subject Checksum. Currently, SHA-1 is the only supported algorithm. It is anticipated that other algorithms will be supported at a later time.") 35 | private Algorithm algorithm; 36 | /** 37 | * The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm. 38 | * 39 | */ 40 | @JsonProperty("checksumValue") 41 | @JsonPropertyDescription("The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm.") 42 | private String checksumValue; 43 | 44 | /** 45 | * Identifies the algorithm used to produce the subject Checksum. Currently, SHA-1 is the only supported algorithm. It is anticipated that other algorithms will be supported at a later time. 46 | * 47 | */ 48 | @JsonProperty("algorithm") 49 | public Algorithm getAlgorithm() { 50 | return algorithm; 51 | } 52 | 53 | /** 54 | * Identifies the algorithm used to produce the subject Checksum. Currently, SHA-1 is the only supported algorithm. It is anticipated that other algorithms will be supported at a later time. 55 | * 56 | */ 57 | @JsonProperty("algorithm") 58 | public void setAlgorithm(Algorithm algorithm) { 59 | this.algorithm = algorithm; 60 | } 61 | 62 | /** 63 | * The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm. 64 | * 65 | */ 66 | @JsonProperty("checksumValue") 67 | public String getChecksumValue() { 68 | return checksumValue; 69 | } 70 | 71 | /** 72 | * The checksumValue property provides a lower case hexidecimal encoded digest value produced using a specific algorithm. 73 | * 74 | */ 75 | @JsonProperty("checksumValue") 76 | public void setChecksumValue(String checksumValue) { 77 | this.checksumValue = checksumValue; 78 | } 79 | 80 | 81 | /** 82 | * Identifies the algorithm used to produce the subject Checksum. Currently, SHA-1 is the only supported algorithm. It is anticipated that other algorithms will be supported at a later time. 83 | * 84 | */ 85 | @Generated("jsonschema2pojo") 86 | public enum Algorithm { 87 | 88 | SHA1("SHA1"), 89 | BLAKE3("BLAKE3"), 90 | SHA_3_384("SHA3-384"), 91 | SHA256("SHA256"), 92 | SHA384("SHA384"), 93 | BLAKE_2_B_512("BLAKE2b-512"), 94 | BLAKE_2_B_256("BLAKE2b-256"), 95 | SHA_3_512("SHA3-512"), 96 | MD2("MD2"), 97 | ADLER32("ADLER32"), 98 | MD4("MD4"), 99 | SHA_3_256("SHA3-256"), 100 | BLAKE_2_B_384("BLAKE2b-384"), 101 | SHA512("SHA512"), 102 | MD6("MD6"), 103 | MD5("MD5"), 104 | SHA224("SHA224"); 105 | private final String value; 106 | private final static Map CONSTANTS = new HashMap(); 107 | 108 | 109 | 110 | Algorithm(String value) { 111 | this.value = value; 112 | } 113 | 114 | @Override 115 | public String toString() { 116 | return this.value; 117 | } 118 | 119 | @JsonValue 120 | public String value() { 121 | return this.value; 122 | } 123 | 124 | @JsonCreator 125 | public static Algorithm fromValue(String value) { 126 | Algorithm constant = CONSTANTS.get(value); 127 | if (constant == null) { 128 | throw new IllegalArgumentException(value); 129 | } else { 130 | return constant; 131 | } 132 | } 133 | 134 | } 135 | 136 | 137 | 138 | 139 | } 140 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/header/header.component.css: -------------------------------------------------------------------------------- 1 | /* 2 | Parts of this file are created by genAI by using GitHub Copilot. 3 | This notice needs to remain attached to any reproduction of or excerpt from this file. 4 | */ 5 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 6 | 7 | SPDX-License-Identifier: MIT */ 8 | .navbar-brand a { 9 | color: #fff; 10 | font-size: 25px; 11 | } 12 | 13 | a { 14 | color: #fff; 15 | } 16 | 17 | a.dropdown-item { 18 | color: #000; 19 | } 20 | 21 | .vertical-align-middle { 22 | vertical-align: middle; 23 | margin-bottom: 3px; 24 | } 25 | 26 | .bg-curation { 27 | background-color: #007bc0; 28 | height: 100%; 29 | } 30 | 31 | .margin-right-10 { 32 | margin-right: 10px; 33 | } 34 | 35 | 36 | .login-button-size { 37 | height: 49px; 38 | width: 50px; 39 | } 40 | 41 | /* .close-btn { 42 | display: none; 43 | } */ 44 | 45 | .logout-icon-style { 46 | font-size: 25px; 47 | margin-right: 1rem; 48 | } 49 | 50 | 51 | .sbomnavbar { 52 | --bs-navbar-padding-x:0; 53 | --bs-navbar-padding-y:0.5rem; 54 | --bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65); 55 | --bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8); 56 | --bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3); 57 | --bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1); 58 | --bs-navbar-brand-padding-y:0.3125rem; 59 | --bs-navbar-brand-margin-end:1rem; 60 | --bs-navbar-brand-font-size:1.25rem; 61 | --bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1); 62 | --bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1); 63 | --bs-navbar-nav-link-padding-x:0.5rem; 64 | --bs-navbar-toggler-padding-y:0.25rem; 65 | --bs-navbar-toggler-padding-x:0.75rem; 66 | --bs-navbar-toggler-font-size:1.25rem; 67 | --bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); 68 | --bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15); 69 | --bs-navbar-toggler-border-radius:var(--bs-border-radius); 70 | --bs-navbar-toggler-focus-width:0.25rem; 71 | --bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out; 72 | position: relative; 73 | display: flex; 74 | flex-wrap: wrap; 75 | align-items: center; 76 | justify-content: space-between; 77 | padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x); 78 | } 79 | .navbar > .container, 80 | .navbar > .container-fluid, 81 | .navbar > .container-lg, 82 | .navbar > .container-md, 83 | .navbar > .container-sm, 84 | .navbar > .container-xl, 85 | .navbar > .container-xxl { 86 | display: flex; 87 | flex-wrap: inherit; 88 | align-items: center; 89 | justify-content: space-between; 90 | } 91 | 92 | .dialogBox-overlay { 93 | position: fixed; 94 | top: 0; 95 | left: 0; 96 | width: 100%; 97 | height: 100%; 98 | background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black background */ 99 | z-index: 1150; /* Ensure it overlays other components */ 100 | display: flex; 101 | justify-content: center; 102 | align-items: center; 103 | } 104 | 105 | .dialogBox { 106 | display: inline-block; /* Ensures the dialog box is treated as an inline-block element */ 107 | background-color: #fff; /* White background for the dialog box */ 108 | border-radius: 8px; /* Rounded corners */ 109 | padding: 20px; /* Padding inside the dialog box */ 110 | width: auto; /* Automatically adjust width based on content */ 111 | max-width: 600px; /* Optional: Set a maximum width */ 112 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Subtle shadow for the dialog box */ 113 | text-align: center; /* Center-align text inside the dialog box */ 114 | position: relative; /* For positioning the close button */ 115 | border-style: groove; 116 | } 117 | 118 | .dialogBox .close-btn { 119 | position: absolute; 120 | top: 10px; 121 | right: 10px; 122 | background: none; 123 | border: none; 124 | font-size: 1.5rem; 125 | font-weight: bold; 126 | color: #000; 127 | cursor: pointer; 128 | z-index: 10; 129 | } 130 | 131 | .dialogBox .close-btn:hover { 132 | color: #ff0000; /* Optional: Change color on hover */ 133 | } 134 | 135 | .modal-box .close-btn { 136 | position: absolute; 137 | top: 10px; 138 | right: 10px; 139 | background: none; 140 | border: none; 141 | font-size: 1.5rem; 142 | font-weight: bold; 143 | color: #000; 144 | cursor: pointer; 145 | } 146 | 147 | .modal-box .close-btn:hover { 148 | color: #ff0000; /* Optional: Change color on hover */ 149 | } 150 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 4 | # SBOM-sg-SEPIA 5 | 6 | The team at Bosch were working on a mapping of SPDX and CycloneDX on both property level (= syntax) and a semantic interpretation of the information. They wrote a schema that describes a bare minimum SBOM on semantic level, and a validator for this. This repo is to explore the work done. 7 | 8 | # SEPIA – SBOM Exchange Procedures, Interfaces and Architecture 9 | 10 | ## Introduction 11 | 12 | SEPIA is a project which focuses on validating SBOMs by using standard SBOM schemas. 13 | 14 | Additionally, we would like to curate an Open SBOM schema library by collecting schemas used across industry. 15 | 16 | It also provides a tooling which helps to validate SBOM schemas and perform operations such as Edit the metadata, Insert missing fields and Merge multiple SBOMs. 17 | 18 | ## Roadmap (Under Discussion) 19 | 20 | 1. Introduce validation checks based on CycloneDX 1.6 schema 21 | 2. A new feature to convert SPDX 2.3 <-> CycloneDX 1.6 based on a custom schema 22 | 3. Version upgrades with schema check for various SPDX and CycloneDX schemas 23 | * SPDX 2.2 --> SPDX 2.3 24 | * SPDX 2.3 --> SPDX 3.0 25 | * CycloneDX 1.4 --> CycloneDX 1.6 26 | * CycloneDX 1.5 --> CycloneDX 1.6 27 | 4. Comparison feature to filter changes between two different versions of SBOM logs 28 | 29 | 30 | ## License 31 | 32 | SEPIA project is licensed under Creative Commons Attribution 4.0 International except for the source code. 33 | 34 | Source code under the folder tools is licensed under MIT license. Please review each license individually. 35 | 36 | SPDX-License-Identifier: CC-BY-4.0 AND MIT 37 | 38 | 39 | For copyrights please see the [CONTRIBUTORS](CONTRIBUTORS) file. 40 | 41 | ## Challenges : 42 | 43 | 1. Currently we have many ways to document SBOMS 44 | 45 | * Competing Standards: SPDX + CycloneDX 46 | 47 | * Every Customer has at least one self-made SBOM format. 48 | 49 | * Legal requirements also often apply, depending on product and market. 50 | 51 | => Cost intensive activity that does not add real value to the end-user. 52 | 53 | 2. SPDX and CycloneDX have overlaps and unique attributes 54 | 55 | * Both have many versions that are not compatible. 56 | 57 | * Mapping is difficult as there is no "babel fish". 58 | 59 | * Merging is difficult as data might get lost. 60 | 61 | * Backward and forward compatibility is not always guaranteed. 62 | 63 | => automation with existing tools is not possible without gambling with your compliance. 64 | 65 | 66 | ## Our Approach : Make it Open Source 67 | 68 | 1. We started an Open Source project. 69 | 70 | * We will provide our evaluation and mapping of SPDX and CycloneDX with semantic definition of important properties. 71 | 72 | * We will provide our SBOM tooling and will continue its development in the Open. 73 | 74 | * We will provide our semantic schema (currently SPDX only). 75 | 76 | * We will curate an Open SBOM Schema Library that can be used for automation. 77 | 78 | 2. We encourage you to participate in this activity. 79 | 80 | * Providing your semantic schema to build an Open SBOM Schema Library. 81 | 82 | * Share your insights and experience to build an SBOM ecosystem that allows an automatic processing of SBOMs independent of the tool used to generate and the format used. 83 | 84 | 3. We will use our experience and assets in the OpenChain activities to define a “common SBOM” – through OpenChain SBOM Study Group. 85 | 86 | 87 | ## The Big Picture: 88 | 89 | ![alt text](Images/SEPIA-workflow.png) 90 | 91 | ## Proposed Solution : 92 | 93 | * Existing schemas were not sufficient and is the root cause of ambiguities. 94 | 95 | * We defined SPDX and CycloneDX schema which reflects our requirements in a machine processible SBOM. 96 | 97 | * The defined schema is used to validate the SBOM. 98 | 99 | * SEPIA lists the syntactic errors which can be resolved using the edit feature of the tooling. 100 | 101 | **Dashboard :** 102 | 103 | ![alt text](Images/Dashboard.png) 104 | 105 | **Edit :** 106 | 107 | ![alt text](Images/image-2.png) 108 | 109 | **Error log :** 110 | 111 | ![alt text](Images/image-3.png) 112 | 113 | ## Docker : 114 | ``` 115 | docker compose up -d 116 | ``` 117 | ## Status : 118 | 119 | * Current features – Validate, Edit, Merge and Integration with SCA tool. 120 | 121 | * In development – Convert (SPDX<-> CycloneDX) and rdf to json converter and dockerization. 122 | 123 | * Future tool focus – Filter, copy and compare. 124 | 125 | * Community focus – collect and distribute schema from other companies. 126 | 127 | 128 | ## Benefits : 129 | 130 | * Ensure machine processable SBOM exchange with semantic relevance. 131 | 132 | * Providing validator to suppliers that would ensure SBOM quality. 133 | 134 | * Purchase teams could use validator for first check of deliveries from their suppliers. 135 | 136 | 137 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.springframework.boot 6 | spring-boot-starter-parent 7 | 2.3.8.RELEASE 8 | 9 | 10 | com.sepia.sbomutils 11 | sbom-utils-service 12 | 2.0 13 | sbom-utils-service 14 | SBOM Utils Service 15 | 16 | 17 | 18 | 19 | 1.8 20 | 2.18.0 21 | 2.14.0 22 | 23 | 24 | 25 | 26 | com.flipkart.zjsonpatch 27 | zjsonpatch 28 | 0.4.16 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-devtools 37 | runtime 38 | true 39 | 40 | 41 | 42 | io.springfox 43 | springfox-swagger2 44 | 2.6.1 45 | compile 46 | 47 | 48 | 49 | io.springfox 50 | springfox-swagger-ui 51 | 2.6.1 52 | compile 53 | 54 | 55 | 56 | org.json 57 | json 58 | 20180813 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-test 64 | test 65 | 66 | 67 | org.junit.vintage 68 | junit-vintage-engine 69 | 70 | 71 | 72 | 73 | 74 | org.powermock 75 | powermock-module-junit4 76 | 2.0.0 77 | test 78 | 79 | 80 | 81 | 82 | org.powermock 83 | powermock-api-mockito2 84 | 2.0.0 85 | test 86 | 87 | 88 | 89 | org.powermock 90 | powermock-api-support 91 | 2.0.0 92 | test 93 | 94 | 95 | 96 | org.cyclonedx 97 | cyclonedx-core-java 98 | 7.3.2 99 | 100 | 101 | 102 | org.spdx 103 | spdx-tools 104 | 2.2.0 105 | 106 | 107 | org.apache.logging.log4j 108 | log4j-slf4j-impl 109 | 110 | 111 | 112 | 113 | 114 | org.spdx 115 | cdx2spdx 116 | 0.1.4 117 | 118 | 119 | org.spdx 120 | spdx-rdf-store 121 | 122 | 123 | 124 | 125 | 126 | org.projectlombok 127 | lombok 128 | 1.18.20 129 | true 130 | 131 | 132 | javax.servlet 133 | jstl 134 | 135 | 136 | javax.servlet 137 | javax.servlet-api 138 | 139 | 140 | com.fasterxml.jackson.core 141 | jackson-databind 142 | 2.14.0 143 | 144 | 145 | 146 | org.apache.jena 147 | apache-jena-libs 148 | 3.9.0 149 | pom 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | org.springframework.boot 159 | spring-boot-maven-plugin 160 | 161 | 162 | 163 | org.projectlombok 164 | lombok 165 | 166 | 167 | 168 | 169 | 170 | org.sonarsource.scanner.maven 171 | sonar-maven-plugin 172 | 3.9.1.2184 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | org.apache.maven.plugins 181 | maven-surefire-report-plugin 182 | 2.22.0 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/src/main/java/com/sepia/sbomutils/util/SbomFileUtils.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | // 3 | // SPDX-License-Identifier: MIT 4 | package com.sepia.sbomutils.util; 5 | 6 | 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.nio.charset.StandardCharsets; 11 | import java.security.MessageDigest; 12 | import java.security.NoSuchAlgorithmException; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.UUID; 16 | import java.util.regex.Matcher; 17 | import java.util.regex.Pattern; 18 | 19 | import org.apache.commons.io.FileUtils; 20 | import org.apache.commons.lang3.StringUtils; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | import org.springframework.stereotype.Component; 24 | import org.springframework.util.FileCopyUtils; 25 | import org.springframework.web.multipart.MultipartFile; 26 | 27 | import com.google.common.hash.Hashing; 28 | import com.google.common.io.Files; 29 | import com.sepia.sbomutils.model.BomFilesInputModel; 30 | import com.sepia.sbomutils.model.ErrorModel; 31 | 32 | @Component 33 | public class SbomFileUtils { 34 | 35 | private static final Logger LOGGER = LoggerFactory.getLogger(SbomFileUtils.class); 36 | 37 | 38 | /** 39 | * 40 | * @param regex 41 | * @param text 42 | * @param group 43 | * @return 44 | */ 45 | public static String regexExtractor(String regex, String text, int group) { 46 | String matchedText = ""; 47 | Pattern pattern = Pattern.compile(regex); 48 | Matcher matcher = pattern.matcher(text); 49 | if (matcher.find()) { 50 | matchedText = matcher.group(group); 51 | } 52 | return matchedText; 53 | } 54 | 55 | /** 56 | * 57 | * @param existingFiles 58 | * @param skipDirName 59 | * @return 60 | */ 61 | public boolean deleteObsoleteDirs(File currentFile, String directoryToSkipDeleting) { 62 | try { 63 | if (currentFile.isDirectory()) { 64 | if (directoryToSkipDeleting == null 65 | || !currentFile.getName().equalsIgnoreCase(directoryToSkipDeleting)) { 66 | FileUtils.deleteDirectory(currentFile); 67 | } 68 | } else { 69 | FileUtils.deleteDirectory(currentFile); 70 | } 71 | return true; 72 | } catch (Exception e) { 73 | LOGGER.error("Exception occured while deleting files >> {}", currentFile.getName(), e); 74 | return false; 75 | } 76 | } 77 | 78 | 79 | /** 80 | * generateUuid() Method used to generate a random UUID for SPDXID 81 | * 82 | * @return 83 | */ 84 | public static String generateUuid() { 85 | UUID uuid = UUID.randomUUID(); 86 | String uuidAsString = uuid.toString(); 87 | return uuidAsString; 88 | } 89 | 90 | /** 91 | * 92 | * @param directory 93 | * @param fileToSave 94 | * @param isSchemaFile 95 | * @return true if the file save operation is successful 96 | */ 97 | public File saveFileInDirectory(File directory, MultipartFile fileToSave, boolean isSchemaFile) { 98 | File uploadedFile = null; 99 | try { 100 | if (!directory.exists()) { 101 | directory.mkdirs(); 102 | } 103 | String fileNameToBeSaved = fileToSave.getOriginalFilename(); 104 | String keyword = isSchemaFile ? "~schema." : "~original."; 105 | 106 | if(!StringUtils.isEmpty(fileNameToBeSaved)) { 107 | String onlyName = Files.getNameWithoutExtension(fileNameToBeSaved); 108 | String revisedFileNameToBeSaved = onlyName + keyword 109 | + fileNameToBeSaved.substring(fileNameToBeSaved.lastIndexOf(".") + 1); 110 | 111 | File currentFile = new File(directory, revisedFileNameToBeSaved); 112 | FileCopyUtils.copy(fileToSave.getBytes(), new FileOutputStream(currentFile)); 113 | 114 | if (!isSchemaFile) { 115 | uploadedFile = new File(directory, fileNameToBeSaved); 116 | FileCopyUtils.copy(fileToSave.getBytes(), new FileOutputStream(uploadedFile)); 117 | } 118 | } 119 | } catch (IOException e) { 120 | LOGGER.error("Exception occured while saving file >> {} in the given directory >> {}", directory.getName(), 121 | fileToSave.getName(), e); 122 | } 123 | 124 | return uploadedFile; 125 | } 126 | 127 | public void sanitizeDirectory(File directoryToSanitize, BomFilesInputModel sbomInputModel) { 128 | try { 129 | if (directoryToSanitize.isDirectory()) { 130 | if (!sbomInputModel.getSchemaType().equalsIgnoreCase(Constants.CUSTOM)) { 131 | FileUtils.deleteDirectory(directoryToSanitize); 132 | } else { 133 | if (!directoryToSanitize.getName().equalsIgnoreCase( 134 | sbomInputModel.getIndex() + Constants.UNDERSCORE + sbomInputModel.getSchemaType())) { 135 | FileUtils.deleteDirectory(directoryToSanitize); 136 | } else { 137 | File[] filesList = directoryToSanitize.listFiles(); 138 | if (filesList.length > 0) { 139 | for (File curFile : filesList) { 140 | if (curFile.getName().contains("~schema")) { 141 | if (sbomInputModel.isSchema()) { 142 | java.nio.file.Files.delete(curFile.toPath()); 143 | } 144 | } else { 145 | if (!sbomInputModel.isSchema()) { 146 | java.nio.file.Files.delete(curFile.toPath()); 147 | } 148 | } 149 | } 150 | } 151 | } 152 | } 153 | } else { 154 | java.nio.file.Files.delete(directoryToSanitize.toPath()); 155 | } 156 | } catch (Exception e) { 157 | LOGGER.error("Exception occured while sanitizing directory before upload >> ", e); 158 | } 159 | 160 | } 161 | 162 | public List getErrorListFromString(String errorString) { 163 | List errorList = new ArrayList<>(); 164 | for (String error : errorString.split("\r\n")) { 165 | String[] keyAndValueSplit = error.split(":"); 166 | if (keyAndValueSplit.length > 1) { 167 | ErrorModel errorModel = new ErrorModel(); 168 | errorModel.setErrorKey(keyAndValueSplit[0]); 169 | errorModel.setMessage(keyAndValueSplit[1]); 170 | errorList.add(errorModel); 171 | } 172 | } 173 | return errorList; 174 | } 175 | 176 | public String generateFileHash(String stringToHash) throws NoSuchAlgorithmException { 177 | 178 | MessageDigest md = MessageDigest.getInstance("SHA-512"); 179 | 180 | byte[] bytes = md.digest(stringToHash.getBytes(StandardCharsets.UTF_8)); 181 | StringBuilder sb = new StringBuilder(); 182 | for (int i = 0; i < bytes.length; i++) { 183 | sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); 184 | } 185 | return sb.toString(); 186 | } 187 | 188 | public String generateFileHash(File fileToHash) throws IOException { 189 | 190 | return Files.hash(fileToHash, Hashing.sha512()).toString(); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/sbom-input/sbom-input.component.css: -------------------------------------------------------------------------------- 1 | /* 2 | Parts of this file are created by genAI by using GitHub Copilot. 3 | This notice needs to remain attached to any reproduction of or excerpt from this file. 4 | */ 5 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 6 | 7 | SPDX-License-Identifier: MIT */ 8 | .row { 9 | margin-bottom: 25px; 10 | } 11 | 12 | .col-md-3-6 { 13 | width: 31%; 14 | flex: 0 0 31%; 15 | max-width: 31%; 16 | } 17 | 18 | .merge-width { 19 | margin: 30px 100px 0 100px; 20 | } 21 | 22 | .required .input { 23 | box-shadow: none; 24 | } 25 | 26 | .loading-container { 27 | position: fixed; 28 | top: 0; 29 | left: 0; 30 | width: 100%; 31 | height: 100%; 32 | display: flex; 33 | justify-content: center; 34 | align-items: center; 35 | background-color: rgba(255, 255, 255, 0.8); /* Optional: Add a semi-transparent background */ 36 | z-index: 9999; /* Ensure it is on top of other elements */ 37 | } 38 | 39 | .form-group { 40 | position: relative; 41 | display: inline-block; 42 | } 43 | .form-group label { 44 | position: absolute; 45 | top: -10px; 46 | left: 10px; 47 | background:white; 48 | padding: 0 5px; 49 | } 50 | .form-select { 51 | padding-top: 20px; 52 | border-color: black; 53 | } 54 | 55 | .form-group { 56 | position: relative; 57 | display: inline-block; 58 | } 59 | .form-group label { 60 | position: absolute; 61 | top: -10px; 62 | left: 10px; 63 | background:white; 64 | padding: 0 5px; 65 | } 66 | .form-select { 67 | padding-top: 20px; 68 | border-color: black; 69 | } 70 | 71 | .alert { 72 | padding: 15px; 73 | margin-bottom: 20px; 74 | border: 1px solid transparent; 75 | border-radius: 4px; 76 | color: #155724; 77 | background-color: #d4edda; 78 | border-color: #c3e6cb; 79 | position: static; 80 | } 81 | 82 | .btn-close { 83 | position: absolute; 84 | top: 10px; 85 | right: 10px; 86 | background: none; 87 | border: none; 88 | font-size: 1.2rem; 89 | cursor: pointer; 90 | } 91 | 92 | .form-check-input { 93 | border-width: 2px; /* Increase the border size */ 94 | border-color: #8c8989; /* Optional: Change the border color */ 95 | width: 18px; /* Optional: Increase the size of the checkbox */ 96 | height: 18px; /* Optional: Increase the size of the checkbox */ 97 | } 98 | 99 | .custom-input { 100 | border-bottom: 0.0625rem solid; 101 | background-color: #f2f2f2; 102 | border: 2px thin black; /* Thick black border */ 103 | border-radius: 4px; /* Optional: Keep the default rounded corners */ 104 | } 105 | 106 | .custom-select-input { 107 | border-bottom: 0.0625rem solid; 108 | background-color: #f2f2f2; 109 | border: 2px thin black; /* Thick black border */ 110 | border-radius: 4px; /* Optional: Keep the default rounded corners */ 111 | padding-top: 10px; 112 | } 113 | 114 | .alert-danger { 115 | background-color: #f8d7da !important; /* Red background */ 116 | color: #721c24 !important; /* Dark red text */ 117 | border-color: #f5c6cb !important; /* Red border */ 118 | } 119 | .alert-info { 120 | background-color: #d1ecf1 !important; /* Light blue background */ 121 | color: #0c5460 !important; /* Dark blue text */ 122 | border-color: #bee5eb !important; /* Blue border */ 123 | } 124 | .alert-warning { 125 | background-color: #fff3cd !important; /* Yellow background */ 126 | color: #856404 !important; /* Dark yellow text */ 127 | border-color: #ffeeba !important; /* Yellow border */ 128 | } 129 | 130 | .loading-container { 131 | position: fixed; 132 | top: 0; 133 | left: 0; 134 | width: 100%; 135 | height: 100%; 136 | background-color: rgba(255, 255, 255, 0.8); /* Semi-transparent background */ 137 | z-index: 1050; /* Ensure it appears above other elements */ 138 | } 139 | 140 | /* Modal overlay background */ 141 | .modal-overlay { 142 | padding-top: 1px; 143 | position: fixed; 144 | top: 0; 145 | left: 0; 146 | width: 100%; 147 | height: 100%; 148 | background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black background */ 149 | display: flex; 150 | justify-content: center; 151 | align-items: center; 152 | z-index: 1050; /* Ensure it appears above other elements */ 153 | } 154 | 155 | .dialogBox-overlay { 156 | position: fixed; 157 | top: 0; 158 | left: 0; 159 | width: 100%; 160 | height: 100%; 161 | background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black background */ 162 | z-index: 1150; /* Ensure it overlays other components */ 163 | display: flex; 164 | justify-content: center; 165 | align-items: center; 166 | } 167 | 168 | .dialogBox { 169 | display: inline-block; /* Ensures the dialog box is treated as an inline-block element */ 170 | background-color: #fff; /* White background for the dialog box */ 171 | border-radius: 8px; /* Rounded corners */ 172 | padding: 20px; /* Padding inside the dialog box */ 173 | width: auto; /* Automatically adjust width based on content */ 174 | max-width: 600px; /* Optional: Set a maximum width */ 175 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Subtle shadow for the dialog box */ 176 | text-align: center; /* Center-align text inside the dialog box */ 177 | position: relative; /* For positioning the close button */ 178 | border-style: groove; 179 | } 180 | 181 | .dialogBox .close-btn { 182 | position: absolute; 183 | top: 10px; 184 | right: 10px; 185 | background: none; 186 | border: none; 187 | font-size: 1.5rem; 188 | font-weight: bold; 189 | color: #000; 190 | cursor: pointer; 191 | } 192 | 193 | .dialogBox .close-btn:hover { 194 | color: #ff0000; /* Optional: Change color on hover */ 195 | } 196 | /* Modal box styling */ 197 | .modal-box { 198 | background-color: #fff; /* White background for the modal */ 199 | border-radius: 8px; /* Rounded corners */ 200 | padding: 20px; /* Padding inside the modal */ 201 | width: 85%; /* Width of the modal box */ 202 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Subtle shadow for the modal */ 203 | position: relative; /* For positioning the close button */ 204 | height: 100%; 205 | overflow: hidden; /* Prevent content from overflowing outside the box */ 206 | display: flex; 207 | flex-direction: column; /* Ensure content and footer are stacked vertically */ 208 | } 209 | 210 | .modal-dialog { 211 | overflow: hidden; 212 | z-index: 1; 213 | } 214 | 215 | /* Close button styling */ 216 | .modal-box .close-btn { 217 | position: absolute; 218 | top: 10px; 219 | right: 10px; 220 | background: none; 221 | border: none; 222 | font-size: 1.5rem; 223 | font-weight: bold; 224 | color: #000; 225 | cursor: pointer; 226 | } 227 | 228 | .modal-box .close-btn:hover { 229 | color: #ff0000; /* Optional: Change color on hover */ 230 | } 231 | 232 | /* Scrollable content inside the modal */ 233 | .modal-content { 234 | flex: 1; /* Take up remaining space */ 235 | overflow-y: auto; /* Enable vertical scrolling if content overflows */ 236 | margin-bottom: 10px; /* Add spacing between content and footer */ 237 | } 238 | 239 | .table-container { 240 | max-height: 450px; /* Set the maximum height for the table container */ 241 | overflow-y: auto; /* Enable vertical scrolling */ 242 | border: 1px solid #ddd; /* Optional: Add a border around the table container */ 243 | margin-bottom: 20px; /* Optional: Add spacing below the table */ 244 | } 245 | 246 | .table-container table { 247 | width: 100%; /* Ensure the table takes up the full width of the container */ 248 | border-collapse: collapse; /* Optional: Collapse table borders */ 249 | } 250 | 251 | .table-container th, 252 | .table-container td { 253 | padding: 8px; /* Add padding to table cells */ 254 | text-align: left; /* Align text to the left */ 255 | border-bottom: 1px solid #ddd; /* Add a border below each row */ 256 | } 257 | 258 | .card-body { 259 | overflow-y: auto; /* Enable vertical scrolling if content overflows */ 260 | max-height: 600px; /* Optional: Limit the height of the card body */ 261 | } 262 | 263 | .container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { 264 | --bs-gutter-x: 1.0rem; 265 | --bs-gutter-y: 0; 266 | width: 100%; 267 | padding-right: calc(var(--bs-gutter-x) * .5); 268 | padding-left: calc(var(--bs-gutter-x) * .5); 269 | margin-right: auto; 270 | margin-left: auto; 271 | } 272 | 273 | 274 | /* Base button styling */ 275 | .sbom-btn { 276 | display: inline-block; 277 | font-size: 1rem; 278 | font-weight: 500; 279 | text-align: center; 280 | text-decoration: none; 281 | padding: 10px 10px; 282 | border-radius: 4px; 283 | border: none; 284 | cursor: pointer; 285 | transition: background-color 0.3s ease, color 0.3s ease; 286 | } 287 | 288 | /* Primary button */ 289 | .sbom-btn.sbom-primary { 290 | background-color: #007bff; /* Bootstrap primary blue */ 291 | color: #fff; /* White text */ 292 | } 293 | 294 | .sbom-btn.sbom-primary:hover { 295 | background-color: #0056b3; /* Darker blue on hover */ 296 | } 297 | 298 | .sbom-btn.sbom-primary:active { 299 | background-color: #004085; /* Even darker blue on active */ 300 | } 301 | 302 | /* Secondary button */ 303 | .sbom-btn.sbom-secondary { 304 | background-color: #6c757d; /* Bootstrap secondary gray */ 305 | color: #fff; /* White text */ 306 | } 307 | 308 | .sbom-btn.sbom-secondary:hover { 309 | background-color: #5a6268; /* Darker gray on hover */ 310 | } 311 | 312 | .sbom-btn.sbom-secondary:active { 313 | background-color: #4e555b; /* Even darker gray on active */ 314 | } 315 | 316 | /* Link-style button */ 317 | .sbom-btn.sbom-link { 318 | background-color: transparent; 319 | color: hsl(221, 72%, 21%); /* Bootstrap link blue */ 320 | text-decoration: none; 321 | } 322 | 323 | .sbom-btn.sbom-link:hover { 324 | color: #0056b3; /* Darker blue on hover */ 325 | text-decoration: none; 326 | } 327 | 328 | .sbom-btn.sbom-link:active { 329 | color: hsl(210, 50%, 98%); /* Even darker blue on active */ 330 | } 331 | 332 | /* Disabled button */ 333 | .sbom-btn:disabled { 334 | background-color: #e0e0e0; /* Light gray */ 335 | color: #a0a0a0; /* Gray text */ 336 | cursor: not-allowed; 337 | } 338 | -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 30 | 31 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 32 | 33 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 34 | 35 | (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and 36 | 37 | (b) You must cause any modified files to carry prominent notices stating that You changed the files; and 38 | 39 | (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 40 | 41 | (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 42 | 43 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 44 | 45 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 46 | 47 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 48 | 49 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 50 | 51 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 52 | 53 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 54 | 55 | END OF TERMS AND CONDITIONS 56 | 57 | APPENDIX: How to apply the Apache License to your work. 58 | 59 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. 60 | 61 | Copyright [yyyy] [name of copyright owner] 62 | 63 | Licensed under the Apache License, Version 2.0 (the "License"); 64 | you may not use this file except in compliance with the License. 65 | You may obtain a copy of the License at 66 | 67 | http://www.apache.org/licenses/LICENSE-2.0 68 | 69 | Unless required by applicable law or agreed to in writing, software 70 | distributed under the License is distributed on an "AS IS" BASIS, 71 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 72 | See the License for the specific language governing permissions and 73 | limitations under the License. 74 | -------------------------------------------------------------------------------- /Tools/sbom-public-ui/src/app/models/spdx.model.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: Copyright (C) 2025 Contributors to SEPIA 2 | 3 | SPDX-License-Identifier: MIT */ 4 | export class SpdxModel { 5 | SPDXID!: string; 6 | annotations: Annotations[] = []; 7 | comment?: string; 8 | creationInfo: CreationInfo = new CreationInfo(); 9 | dataLicense!: string; 10 | externalDocumentRefs: ExternalDocumentRefs[] = []; 11 | hasExtractedLicensingInfos: HasExtractedLicensingInfos[] = []; 12 | name!: string; 13 | revieweds: Revieweds[] = []; 14 | spdxVersion!: string; 15 | documentNamespace!: string; 16 | documentDescribes?: string[]; 17 | packages: Packages[] = []; 18 | files: Files[] = []; 19 | snippets: Snippets[] = []; 20 | relationships: Relationships[] = []; 21 | } 22 | 23 | 24 | export class Annotations { 25 | annotationDate!: string; 26 | annotationType!: "OTHER" | "REVIEW"; 27 | annotator!: string; 28 | comment!: string; 29 | } 30 | 31 | export class CreationInfo { 32 | comment?: string; 33 | created!: string; 34 | creators!: [String, ...String[]]; 35 | licenseListVersion?: string; 36 | } 37 | 38 | 39 | export class ExternalDocumentRefs { 40 | checksum!: { 41 | algorithm: 42 | | "SHA1" 43 | | "BLAKE3" 44 | | "SHA3-384" 45 | | "SHA256" 46 | | "SHA384" 47 | | "BLAKE2b-512" 48 | | "BLAKE2b-256" 49 | | "SHA3-512" 50 | | "MD2" 51 | | "ADLER32" 52 | | "MD4" 53 | | "SHA3-256" 54 | | "BLAKE2b-384" 55 | | "SHA512" 56 | | "MD6" 57 | | "MD5" 58 | | "SHA224"; 59 | checksumValue: string; 60 | } 61 | externalDocumentId!: string; 62 | spdxDocument!: string; 63 | } 64 | 65 | export class HasExtractedLicensingInfos { 66 | comment?: string; 67 | crossRefs:crossRefs[] = []; 68 | extractedText!: string; 69 | licenseId!: string; 70 | name?: string; 71 | seeAlsos?: string[]; 72 | } 73 | 74 | export class crossRefs { 75 | isLive?: boolean; 76 | isValid?: boolean; 77 | isWayBackLink?: boolean; 78 | match?: string; 79 | order?: number; 80 | timestamp?: string; 81 | url!: string; 82 | } 83 | 84 | export class Revieweds { 85 | comment?: string; 86 | reviewDate!: string; 87 | reviewer?: string; 88 | } 89 | 90 | 91 | export class Packages { 92 | SPDXID!: string; 93 | annotations?: { 94 | annotationDate: string; 95 | annotationType: "OTHER" | "REVIEW"; 96 | annotator: string; 97 | comment: string; 98 | }[]; 99 | attributionTexts?: string[]; 100 | builtDate?: string; 101 | checksums?: { 102 | algorithm: 103 | | "SHA1" 104 | | "BLAKE3" 105 | | "SHA3-384" 106 | | "SHA256" 107 | | "SHA384" 108 | | "BLAKE2b-512" 109 | | "BLAKE2b-256" 110 | | "SHA3-512" 111 | | "MD2" 112 | | "ADLER32" 113 | | "MD4" 114 | | "SHA3-256" 115 | | "BLAKE2b-384" 116 | | "SHA512" 117 | | "MD6" 118 | | "MD5" 119 | | "SHA224"; 120 | checksumValue: string; 121 | }[]; 122 | comment?: string; 123 | copyrightText?: string; 124 | description?: string; 125 | downloadLocation!: string; 126 | externalRefs: externalRefs[] = []; 127 | // externalRefs?: { 128 | // comment?: string; 129 | // referenceCategory: 130 | // | "OTHER" 131 | // | "PERSISTENT-ID" 132 | // | "PERSISTENT_ID" 133 | // | "SECURITY" 134 | // | "PACKAGE-MANAGER" 135 | // | "PACKAGE_MANAGER"; 136 | // referenceLocator: string; 137 | // referenceType: string; 138 | // }[]; 139 | filesAnalyzed?: boolean; 140 | /** 141 | * @deprecated 142 | * DEPRECATED: use relationships instead of this field. Indicates that a particular file belongs to a package. 143 | */ 144 | hasFiles?: string[]; 145 | homepage?: string; 146 | licenseComments?: string; 147 | licenseConcluded?: string; 148 | licenseDeclared?: string; 149 | licenseInfoFromFiles?: string[]; 150 | name!: string; 151 | originator?: string; 152 | packageFileName?: string; 153 | packageVerificationCode?: { 154 | packageVerificationCodeExcludedFiles?: string[]; 155 | packageVerificationCodeValue: string; 156 | }; 157 | primaryPackagePurpose?: 158 | | null 159 | | "OTHER" 160 | | "INSTALL" 161 | | "ARCHIVE" 162 | | "FIRMWARE" 163 | | "APPLICATION" 164 | | "FRAMEWORK" 165 | | "LIBRARY" 166 | | "CONTAINER" 167 | | "SOURCE" 168 | | "DEVICE" 169 | | "OPERATING_SYSTEM" 170 | | "FILE"; 171 | releaseDate?: string; 172 | sourceInfo?: string; 173 | summary?: string; 174 | supplier?: string; 175 | validUntilDate?: string; 176 | versionInfo?: string; 177 | } 178 | 179 | export enum primaryPackagePurpose { 180 | OTHER = "OTHER", 181 | INSTALL = "INSTALL", 182 | ARCHIVE = "ARCHIVE", 183 | FIRMWARE = "FIRMWARE", 184 | APPLICATION = "APPLICATION", 185 | FRAMEWORK = "FRAMEWORK", 186 | LIBRARY = "LIBRARY", 187 | CONTAINER = "CONTAINER", 188 | SOURCE = "SOURCE", 189 | DEVICE = "DEVICE", 190 | OPERATING_SYSTEM = "OPERATING_SYSTEM", 191 | FILE = "FILE" 192 | }; 193 | export class Files { 194 | SPDXID!: string; 195 | annotations?: { 196 | annotationDate: string; 197 | annotationType: "OTHER" | "REVIEW"; 198 | annotator: string; 199 | comment: string; 200 | }[]; 201 | artifactOfs?: { 202 | [k: string]: unknown; 203 | }[]; 204 | attributionTexts?: string[]; 205 | checksums?: [ 206 | { 207 | /** 208 | * Identifies the algorithm used to produce the subject Checksum. Currently, SHA-1 is the only supported algorithm. It is anticipated that other algorithms will be supported at a later time. 209 | */ 210 | algorithm: 211 | | "SHA1" 212 | | "BLAKE3" 213 | | "SHA3-384" 214 | | "SHA256" 215 | | "SHA384" 216 | | "BLAKE2b-512" 217 | | "BLAKE2b-256" 218 | | "SHA3-512" 219 | | "MD2" 220 | | "ADLER32" 221 | | "MD4" 222 | | "SHA3-256" 223 | | "BLAKE2b-384" 224 | | "SHA512" 225 | | "MD6" 226 | | "MD5" 227 | | "SHA224"; 228 | checksumValue: string; 229 | }, 230 | ...{ 231 | algorithm: 232 | | "SHA1" 233 | | "BLAKE3" 234 | | "SHA3-384" 235 | | "SHA256" 236 | | "SHA384" 237 | | "BLAKE2b-512" 238 | | "BLAKE2b-256" 239 | | "SHA3-512" 240 | | "MD2" 241 | | "ADLER32" 242 | | "MD4" 243 | | "SHA3-256" 244 | | "BLAKE2b-384" 245 | | "SHA512" 246 | | "MD6" 247 | | "MD5" 248 | | "SHA224"; 249 | checksumValue: string; 250 | }[] 251 | ]; 252 | comment?: string; 253 | copyrightText?: string; 254 | fileContributors?: string[]; 255 | /** 256 | * @deprecated 257 | * This field is deprecated since SPDX 2.0 in favor of using Section 7 which provides more granularity about relationships. 258 | */ 259 | fileDependencies?: string[]; 260 | fileName!: string; 261 | fileTypes?: ( 262 | | "OTHER" 263 | | "DOCUMENTATION" 264 | | "IMAGE" 265 | | "VIDEO" 266 | | "ARCHIVE" 267 | | "SPDX" 268 | | "APPLICATION" 269 | | "SOURCE" 270 | | "BINARY" 271 | | "TEXT" 272 | | "AUDIO" 273 | )[]; 274 | licenseComments?: string; 275 | licenseConcluded?: string; 276 | licenseInfoInFiles?: string[]; 277 | noticeText?: string; 278 | } 279 | 280 | export class Snippets { 281 | SPDXID!: string; 282 | annotations?: { 283 | annotationDate: string; 284 | annotationType: "OTHER" | "REVIEW"; 285 | annotator: string; 286 | comment: string; 287 | }[]; 288 | attributionTexts?: string[]; 289 | comment?: string; 290 | copyrightText?: string; 291 | licenseComments?: string; 292 | licenseConcluded?: string; 293 | licenseInfoInSnippets?: string[]; 294 | name!: string; 295 | ranges!: [ 296 | { 297 | endPointer: { 298 | reference: string; 299 | offset?: number; 300 | lineNumber?: number; 301 | }; 302 | startPointer: { 303 | reference: string; 304 | offset?: number; 305 | lineNumber?: number; 306 | }; 307 | }, 308 | ...{ 309 | endPointer: { 310 | reference: string; 311 | offset?: number; 312 | lineNumber?: number; 313 | }; 314 | startPointer: { 315 | reference: string; 316 | offset?: number; 317 | lineNumber?: number; 318 | }; 319 | }[] 320 | ]; 321 | snippetFromFile!: string; 322 | } 323 | 324 | export class Relationships { 325 | spdxElementId!: string; 326 | comment?: string; 327 | relatedSpdxElement!: string; 328 | relationshipType!: 329 | | "VARIANT_OF" 330 | | "COPY_OF" 331 | | "PATCH_FOR" 332 | | "TEST_DEPENDENCY_OF" 333 | | "CONTAINED_BY" 334 | | "DATA_FILE_OF" 335 | | "OPTIONAL_COMPONENT_OF" 336 | | "ANCESTOR_OF" 337 | | "GENERATES" 338 | | "CONTAINS" 339 | | "OPTIONAL_DEPENDENCY_OF" 340 | | "FILE_ADDED" 341 | | "REQUIREMENT_DESCRIPTION_FOR" 342 | | "DEV_DEPENDENCY_OF" 343 | | "DEPENDENCY_OF" 344 | | "BUILD_DEPENDENCY_OF" 345 | | "DESCRIBES" 346 | | "PREREQUISITE_FOR" 347 | | "HAS_PREREQUISITE" 348 | | "PROVIDED_DEPENDENCY_OF" 349 | | "DYNAMIC_LINK" 350 | | "DESCRIBED_BY" 351 | | "METAFILE_OF" 352 | | "DEPENDENCY_MANIFEST_OF" 353 | | "PATCH_APPLIED" 354 | | "RUNTIME_DEPENDENCY_OF" 355 | | "TEST_OF" 356 | | "TEST_TOOL_OF" 357 | | "DEPENDS_ON" 358 | | "SPECIFICATION_FOR" 359 | | "FILE_MODIFIED" 360 | | "DISTRIBUTION_ARTIFACT" 361 | | "AMENDS" 362 | | "DOCUMENTATION_OF" 363 | | "GENERATED_FROM" 364 | | "STATIC_LINK" 365 | | "OTHER" 366 | | "BUILD_TOOL_OF" 367 | | "TEST_CASE_OF" 368 | | "PACKAGE_OF" 369 | | "DESCENDANT_OF" 370 | | "FILE_DELETED" 371 | | "EXPANDED_FROM_ARCHIVE" 372 | | "DEV_TOOL_OF" 373 | | "EXAMPLE_OF"; 374 | } 375 | 376 | 377 | export class externalRefs { 378 | comment?: string; 379 | referenceCategory!: 380 | | null 381 | | "OTHER" 382 | | "PERSISTENT-ID" 383 | | "PERSISTENT_ID" 384 | | "SECURITY" 385 | | "PACKAGE-MANAGER" 386 | | "PACKAGE_MANAGER"; 387 | referenceLocator?: string; 388 | referenceType?: string; 389 | } 390 | -------------------------------------------------------------------------------- /Tools/sbom-public-service/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | --------------------------------------------------------------------------------