Artifact Encryption plug point (#1202)

* added ArtifactEncryption interface, injected it into SM creation UI module, added encryption metadata key generation upon SM creation, used encryptor during file upload

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* add default artifact encryption implementation based on gcm aes algorithm

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* changed ArtifactEncryptor interface to manage encryption secrets by itself

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* cleaned up stale code, fixed sonar

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* fixed software module encryption within transaction

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added artifact encryption secrets store

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* extended ArtifactEncryption interface to allow decryption, secrets store provides removeSecret, added missing javadocs

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* intriduced DbArtifact interface, use EncryptionAwareDbArtifact for artifact decryption during download

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* introduced ArtifactEncryptionService to minimize duplications and unneccessary dependency injections

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* declared ArtifactEncryptionService as a bean

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added persistant encryption flag to software module

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* further adptations for encryption flag persistence

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added ArtifactEncryptionException, fixed encryption check in UI

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added encryption error handling

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added encrypted flag to DDI/DMF, adapted exception handling

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* adapted rest docs

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* Add test to verify artifact encryption is not given by default

Signed-off-by: Florian Ruschbaschan <Florian.Ruschbaschan@bosch.io>

* Add isEncrypted() to toString() of JpaSoftwareModule, fix typos

Signed-off-by: Florian Ruschbaschan <Florian.Ruschbaschan@bosch.io>

* Fix sql migration scripts

Signed-off-by: Florian Ruschbaschan <Florian.Ruschbaschan@bosch.io>

* Calculate encrypted artifact size by subtract encryption size overhead

Signed-off-by: Florian Ruschbaschan <Florian.Ruschbaschan@bosch.io>

* publish upload failed without waiting for interuption during UI file upload

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* upgraded cron utils to 9.1.6

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

Co-authored-by: Florian Ruschbaschan <Florian.Ruschbaschan@bosch.io>
This commit is contained in:
Bondar Bogdan
2021-11-18 09:07:05 +01:00
committed by GitHub
parent 7e28fba104
commit 146735012a
74 changed files with 1214 additions and 324 deletions

View File

@@ -60,7 +60,7 @@ final class DdiApiModelProperties {
static final String CHUNK_TYPE = "Type of the chunk, e.g. firmware, bundle, app. In update server mapped to Software Module Type.";
static final String SOFTWARE_MODUL_TYPE = "type of the software module, e.g. firmware, bundle, app";
static final String SOFTWARE_MODULE_TYPE = "type of the software module, e.g. firmware, bundle, app";
static final String SOFTWARE_MODULE_VERSION = "version of the software module";
@@ -68,7 +68,7 @@ final class DdiApiModelProperties {
static final String SOFTWARE_MODULE_ARTIFACT_LINKS = "artifact links of the software module";
static final String SOFTWARE_MODUL_ID = "id of the software module";
static final String SOFTWARE_MODULE_ID = "id of the software module";
static final String CHUNK_VERSION = "software version of the chunk";
@@ -102,15 +102,15 @@ final class DdiApiModelProperties {
static final String CHUNK = "Software chunks of an update. In server mapped by Software Module.";
static final String SOFTWARE_MODUL = "software modules of an update";
static final String SOFTWARE_MODULE = "software modules of an update";
static final String ARTIFACT = "artifact modules of an update";
static final String FILENAME = "file name of artifact";
static final String TARGET_CONFIG_DATA = "Link which is provided whenever the provisioning target or device is supposed "
+ "to push its configuration data (aka. \"controller attributes\") to the server. Only shown for the initial "
+ "configuration, after a successful update action, or if requested explicitly (e.g. via the management UI).";
+ "to push its configuration data (aka. \"controller attributes\") to the server. Only shown for the initial "
+ "configuration, after a successful update action, or if requested explicitly (e.g. via the management UI).";
static final String ARTIFACT_HASHES_SHA1 = "SHA1 hash of the artifact in Base 16 format";
static final String ARTIFACT_HASHES_MD5 = "MD5 hash of the artifact";

View File

@@ -183,7 +183,9 @@ public class RootControllerDocumentationTest extends AbstractApiRestDocumentatio
pathParameters(parameterWithName("tenant").description(ApiModelPropertiesGeneric.TENANT),
parameterWithName("controllerId").description(DdiApiModelProperties.CONTROLLER_ID),
parameterWithName("actionId").description(DdiApiModelProperties.ACTION_ID_CANCELED)),
requestFields(optionalRequestFieldWithPath("id").description(DdiApiModelProperties.FEEDBACK_ACTION_ID),
requestFields(
optionalRequestFieldWithPath("id")
.description(DdiApiModelProperties.FEEDBACK_ACTION_ID),
requestFieldWithPath("status").description(DdiApiModelProperties.TARGET_STATUS),
requestFieldWithPath("status.execution")
.description(DdiApiModelProperties.TARGET_EXEC_STATUS).type("enum")
@@ -386,7 +388,9 @@ public class RootControllerDocumentationTest extends AbstractApiRestDocumentatio
parameterWithName("controllerId").description(DdiApiModelProperties.CONTROLLER_ID),
parameterWithName("actionId").description(DdiApiModelProperties.ACTION_ID)),
requestFields(optionalRequestFieldWithPath("id").description(DdiApiModelProperties.FEEDBACK_ACTION_ID),
requestFields(
optionalRequestFieldWithPath("id")
.description(DdiApiModelProperties.FEEDBACK_ACTION_ID),
requestFieldWithPath("status").description(DdiApiModelProperties.TARGET_STATUS),
requestFieldWithPath("status.execution")
.description(DdiApiModelProperties.TARGET_EXEC_STATUS).type("enum")
@@ -428,7 +432,7 @@ public class RootControllerDocumentationTest extends AbstractApiRestDocumentatio
.andDo(this.document.document(
pathParameters(parameterWithName("tenant").description(ApiModelPropertiesGeneric.TENANT),
parameterWithName("controllerId").description(DdiApiModelProperties.CONTROLLER_ID),
parameterWithName("moduleId").description(DdiApiModelProperties.SOFTWARE_MODUL_ID)),
parameterWithName("moduleId").description(DdiApiModelProperties.SOFTWARE_MODULE_ID)),
responseFields(fieldWithPath("[]filename").description(DdiApiModelProperties.ARTIFACTS),
fieldWithPath("[]hashes").description(DdiApiModelProperties.ARTIFACTS),
fieldWithPath("[]hashes.sha1").description(DdiApiModelProperties.ARTIFACT_HASHES_SHA1),

View File

@@ -43,6 +43,7 @@ public final class MgmtApiModelProperties {
// software module
public static final String SM_TYPE = "The software module type " + ApiModelPropertiesGeneric.ENDING;
public static final String ENCRYPTED = "Encryption flag, used to identify that artifacts should be encrypted upon upload.";
public static final String ARTIFACT_HASHES = "Hashes of the artifact.";
public static final String ARTIFACT_SIZE = "Size of the artifact.";
public static final String ARTIFACT_PROVIDED_FILE = "Binary of file.";

View File

@@ -84,6 +84,7 @@ public class SoftwaremodulesDocumentationTest extends AbstractApiRestDocumentati
fieldWithPath("content[].name").description(ApiModelPropertiesGeneric.NAME),
fieldWithPath("content[].description").description(ApiModelPropertiesGeneric.DESCRPTION),
fieldWithPath("content[].vendor").description(MgmtApiModelProperties.VENDOR),
fieldWithPath("content[].encrypted").description(MgmtApiModelProperties.ENCRYPTED),
fieldWithPath("content[].createdBy").description(ApiModelPropertiesGeneric.CREATED_BY),
fieldWithPath("content[].createdAt").description(ApiModelPropertiesGeneric.CREATED_AT),
fieldWithPath("content[].lastModifiedBy")
@@ -141,6 +142,7 @@ public class SoftwaremodulesDocumentationTest extends AbstractApiRestDocumentati
fieldWithPath("[].name").description(ApiModelPropertiesGeneric.NAME),
fieldWithPath("[].description").description(ApiModelPropertiesGeneric.DESCRPTION),
fieldWithPath("[].vendor").description(MgmtApiModelProperties.VENDOR),
fieldWithPath("[].encrypted").description(MgmtApiModelProperties.ENCRYPTED),
fieldWithPath("[].deleted").description(ApiModelPropertiesGeneric.DELETED),
fieldWithPath("[].createdBy").description(ApiModelPropertiesGeneric.CREATED_BY),
fieldWithPath("[].createdAt").description(ApiModelPropertiesGeneric.CREATED_AT),
@@ -188,6 +190,7 @@ public class SoftwaremodulesDocumentationTest extends AbstractApiRestDocumentati
fieldWithPath("lastModifiedBy").description(ApiModelPropertiesGeneric.LAST_MODIFIED_BY),
fieldWithPath("lastModifiedAt").description(ApiModelPropertiesGeneric.LAST_MODIFIED_AT),
fieldWithPath("vendor").description(MgmtApiModelProperties.VENDOR),
fieldWithPath("encrypted").description(MgmtApiModelProperties.ENCRYPTED),
fieldWithPath("deleted").description(ApiModelPropertiesGeneric.DELETED),
fieldWithPath("type").description(MgmtApiModelProperties.SM_TYPE),
fieldWithPath("version").description(MgmtApiModelProperties.VERSION),
@@ -227,6 +230,7 @@ public class SoftwaremodulesDocumentationTest extends AbstractApiRestDocumentati
fieldWithPath("type").description(MgmtApiModelProperties.SM_TYPE),
fieldWithPath("version").description(MgmtApiModelProperties.VERSION),
fieldWithPath("vendor").description(MgmtApiModelProperties.VENDOR),
fieldWithPath("encrypted").description(MgmtApiModelProperties.ENCRYPTED),
fieldWithPath("deleted").description(ApiModelPropertiesGeneric.DELETED),
fieldWithPath("_links.self").ignored(),
fieldWithPath("_links.type").description(MgmtApiModelProperties.SM_TYPE),
@@ -279,7 +283,9 @@ public class SoftwaremodulesDocumentationTest extends AbstractApiRestDocumentati
final byte random[] = RandomStringUtils.random(5).getBytes();
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
mockMvc.perform(fileUpload(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts", sm.getId()).file(file))
mockMvc.perform(
fileUpload(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts",
sm.getId()).file(file))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(content().contentType(MediaTypes.HAL_JSON))
.andDo(this.document.document(
@@ -313,7 +319,8 @@ public class SoftwaremodulesDocumentationTest extends AbstractApiRestDocumentati
final byte random[] = RandomStringUtils.random(5).getBytes();
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
mockMvc.perform(fileUpload(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts",
mockMvc.perform(
fileUpload(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts",
sm.getId()).file(file).param("filename", "filename").param("file", "s")
.param("md5sum", "md5sum").param("sha1sum", "sha1sum"))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest())