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:
@@ -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";
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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.";
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user