diff --git a/AutomaticComponentToolkit/lib3mf.xml b/AutomaticComponentToolkit/lib3mf.xml
index 0a9ab13ba..57668fd41 100644
--- a/AutomaticComponentToolkit/lib3mf.xml
+++ b/AutomaticComponentToolkit/lib3mf.xml
@@ -1346,6 +1346,7 @@
+
diff --git a/Include/API/lib3mf_keystore.hpp b/Include/API/lib3mf_keystore.hpp
index cfc4bb2b6..c89e0e1b1 100644
--- a/Include/API/lib3mf_keystore.hpp
+++ b/Include/API/lib3mf_keystore.hpp
@@ -95,7 +95,7 @@ namespace Lib3MF {
virtual IResourceDataGroup * GetResourceDataGroup(const Lib3MF_uint64 nResourceDataIndex) override;
- virtual IResourceDataGroup * AddResourceDataGroup() override;
+ virtual IResourceDataGroup * AddResourceDataGroup(const Lib3MF_uint64 nContentEncryptionKeyBufferSize, const Lib3MF_uint8 * pContentEncryptionKeyBuffer) override;
virtual void RemoveResourceDataGroup(IResourceDataGroup * pTheResourceDataGroup) override;
diff --git a/Source/API/lib3mf_keystore.cpp b/Source/API/lib3mf_keystore.cpp
index d4b7684c6..92f446711 100644
--- a/Source/API/lib3mf_keystore.cpp
+++ b/Source/API/lib3mf_keystore.cpp
@@ -86,13 +86,20 @@ IResourceDataGroup * Lib3MF::Impl::CKeyStore::GetResourceDataGroup(const Lib3MF_
return new CResourceDataGroup(dg);
}
-IResourceDataGroup * Lib3MF::Impl::CKeyStore::AddResourceDataGroup() {
+IResourceDataGroup * Lib3MF::Impl::CKeyStore::AddResourceDataGroup(const Lib3MF_uint64 nContentEncryptionKeyBufferSize, const Lib3MF_uint8 * pContentEncryptionKeyBuffer) {
//this is not ideal, as key size is determined by the encryptionalgorithm inside resourcedata.
- //in any case, the spec does not state what happens if different resource datas have different algorithms,
- //but resourcedatagroups are supposed to group the same key for a group of resources...
+ //in any case, the spec does not state what happens if different resource datas have different algorithms.
+ //resourcedatagroups are supposed to group the same key for resourcedatas.
+ //at resource data, we should assert key size maches the algorithm chosen.
//so far, this should work as aes256 is the only thing we support.
std::vector key(NMR::fnGetAlgorithmKeySize(NMR::eKeyStoreEncryptAlgorithm::AES256_GCM), 0);
- m_pModel->generateRandomBytes(key.data(), key.size());
+ if (nContentEncryptionKeyBufferSize == 0) {
+ m_pModel->generateRandomBytes(key.data(), key.size());
+ } else if ((key.size() != nContentEncryptionKeyBufferSize) || (nullptr == pContentEncryptionKeyBuffer)) {
+ throw ELib3MFInterfaceException(LIB3MF_ERROR_INVALIDPARAM);
+ } else {
+ std::copy(pContentEncryptionKeyBuffer, pContentEncryptionKeyBuffer + nContentEncryptionKeyBufferSize, key.data());
+ }
NMR::PKeyStoreResourceDataGroup dg = NMR::CKeyStoreFactory::makeResourceDataGroup(std::make_shared(), key);
m_pKeyStore->addResourceDataGroup(dg);
return new CResourceDataGroup(dg);
diff --git a/Tests/CPP_Bindings/Source/EncryptionMethods.cpp b/Tests/CPP_Bindings/Source/EncryptionMethods.cpp
index b35a7b00f..474fd22a2 100644
--- a/Tests/CPP_Bindings/Source/EncryptionMethods.cpp
+++ b/Tests/CPP_Bindings/Source/EncryptionMethods.cpp
@@ -93,7 +93,7 @@ namespace Lib3MF {
ASSERT_NE(nullptr, meshObj);
auto keyStore = modelToCrpt->GetKeyStore();
auto consumer = keyStore->AddConsumer("LIB3MF#TEST", "contentKey", publicKey);
- auto rdGroup = keyStore->AddResourceDataGroup();
+ auto rdGroup = keyStore->AddResourceDataGroup(ByteVector());
rdGroup->AddAccessRight(consumer.get(),
eWrappingAlgorithm::RSA_OAEP,
eMgfAlgorithm::MGF1_SHA1,
@@ -203,7 +203,7 @@ namespace Lib3MF {
Lib3MF::PConsumer consumer = keyStore->AddConsumer(consumerId, keyId, keyValue);
//add a resource data group
- Lib3MF::PResourceDataGroup dataGroup = keyStore->AddResourceDataGroup();
+ Lib3MF::PResourceDataGroup dataGroup = keyStore->AddResourceDataGroup(ByteVector());
//establish consumer access to the datagroup
Lib3MF::PAccessRight accessRight = dataGroup->AddAccessRight(
diff --git a/Tests/CPP_Bindings/Source/SecureContent.cpp b/Tests/CPP_Bindings/Source/SecureContent.cpp
index 9d4fe82f4..3ee948b55 100644
--- a/Tests/CPP_Bindings/Source/SecureContent.cpp
+++ b/Tests/CPP_Bindings/Source/SecureContent.cpp
@@ -188,7 +188,7 @@ namespace Lib3MF {
ASSERT_NE(nullptr, meshObj);
auto keyStore = modelToCrpt->GetKeyStore();
auto consumer = keyStore->AddConsumer("LIB3MF#TEST", "contentKey", publicKey);
- auto rdGroup = keyStore->AddResourceDataGroup();
+ auto rdGroup = keyStore->AddResourceDataGroup(std::vector());
rdGroup->AddAccessRight(consumer.get(),
eWrappingAlgorithm::RSA_OAEP,
eMgfAlgorithm::MGF1_SHA1,
@@ -296,7 +296,7 @@ namespace Lib3MF {
std::string path1 = "/3D/nonrootmodel1.model";
auto part1 = model->FindOrCreatePackagePart(path1);
- auto dataGroup = keyStore->AddResourceDataGroup();
+ auto dataGroup = keyStore->AddResourceDataGroup(std::vector());
std::string dguuid = dataGroup->GetKeyUUID();
ASSERT_FALSE(dguuid.empty());
@@ -321,14 +321,14 @@ namespace Lib3MF {
std::string path1 = "/3D/nonrootmodel1.model";
auto part1 = model->FindOrCreatePackagePart(path1);
- auto dataGroup1 = keyStore->AddResourceDataGroup();
+ auto dataGroup1 = keyStore->AddResourceDataGroup(std::vector());
keyStore->AddResourceData(dataGroup1.get(), part1.get(), Lib3MF::eEncryptionAlgorithm::AES256_GCM, Lib3MF::eCompression::Deflate, std::vector());
std::string path2 = "/3D/nonrootmodel2.model";
auto part2 = model->FindOrCreatePackagePart(path2);
- auto dataGroup2 = keyStore->AddResourceDataGroup();
+ auto dataGroup2 = keyStore->AddResourceDataGroup(std::vector());
keyStore->AddResourceData(dataGroup2.get(), part2.get(), Lib3MF::eEncryptionAlgorithm::AES256_GCM, Lib3MF::eCompression::Deflate, std::vector());