Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization: Signature for Body+ObjectId #154

Open
lurenpluto opened this issue Mar 30, 2023 Discussed in #128 · 5 comments
Open

Optimization: Signature for Body+ObjectId #154

lurenpluto opened this issue Mar 30, 2023 Discussed in #128 · 5 comments
Assignees
Labels
Any Idea Any problem/ideas/suggestions Codec Encode & Decode for the Object cyfs-base Functions and components in cyfs-base project Object Object design, codec and usage

Comments

@lurenpluto
Copy link
Member

Discussed in #128

Originally posted by streetycat March 17, 2023
I find that, I need to sign Body and Desc separately if I want to prove the authenticity of the object. It consumes a lot of space and efficiency.

If we add the ObjectId into the signature data, we can achieve the same with the signature:

Sign(Hash(Body+ObjectId))

@lurenpluto lurenpluto added the Any Idea Any problem/ideas/suggestions label Mar 30, 2023
@lurenpluto lurenpluto self-assigned this Mar 30, 2023
@lurenpluto lurenpluto added Object Object design, codec and usage cyfs-base Functions and components in cyfs-base project labels Mar 31, 2023
@lurenpluto
Copy link
Member Author

If this problem is to be solved, there are currently two options under consideration.

  1. Modify in the signature section
    This seems to be the most direct method, but it feels strange to add a signature type. The current signature is the signature of the desc and body parts. If you need to customize the body part signature and introduce the type, it may increase additional mental burden.

  2. Add the object_id field in the body part
    In the current body section, add the following fields:

object_id: Option<ObjectId>

If this field is specified, it means that the body has been bound to the target desc, and the body is signed on this basis, which is the overall signature

When verifying whether the body has a desc.public_key signature, two things need to be done

  • If body.object_id is not None, then we need to check whether it matches at first
  • Use desc.public_key to verify whether the signature of the body is valid

The potential risk of this scheme is the codec compatibility problem caused by the introduction of fields

@lurenpluto
Copy link
Member Author

At present, in cyfs system, with mut-body objects unless special needs, is not recommended, in a relatively small number of cases will be used, there are generally the following two situations:

  1. Local use in cyfs-stack
    Only in the stack internal use, such as StorageObject, to maintain data consistency is also the simplest, in this case is not the need for signature and other measures

  2. Used through MetaChain
    If you need to "expose" the object to the outside, then you need strong consistency, such as the current People, Device objects, these objects are currently published, updated and queried through MetaChain.

If the MetaChain is used, only the owner of the object has the right to update the object, and if others "forge" the object, they cannot update the MetaChain, and it is difficult to proliferate in the cyfs network, so this "attack problem" can be avoided to some extent. So to some extent, this "attack problem" can be avoided, but there is still a potential risk

So in the long term, it is necessary to provide a mechanism to avoid this possible risk from a security and completeness perspective

@lurenpluto
Copy link
Member Author

If this problem is to be solved, there are currently two options under consideration.

  1. Modify in the signature section
    This seems to be the most direct method, but it feels strange to add a signature type. The current signature is the signature of the desc and body parts. If you need to customize the body part signature and introduce the type, it may increase additional mental burden.
  2. Add the object_id field in the body part
    In the current body section, add the following fields:
object_id: Option<ObjectId>

If this field is specified, it means that the body has been bound to the target desc, and the body is signed on this basis, which is the overall signature

When verifying whether the body has a desc.public_key signature, two things need to be done

  • If body.object_id is not None, then we need to check whether it matches at first
  • Use desc.public_key to verify whether the signature of the body is valid

The potential risk of this scheme is the codec compatibility problem caused by the introduction of fields

Currently, we are considering using the solution mentioned in 2, which involves the following changes.

  1. Modify ObjectMutBody
    Add an optional field inside the ObjectMutBody
object_id: Option<ObjectId>

Also, add flags for coding compatibility

pub const OBJECT_BODY_FLAG_OBJECT_ID: u8 = 0x01 << 3.
  1. when generating object, someone can choose body.object_id = desc.object_id to achieve the binding of body and desc
  2. Everyone need to check whether body.object_id matches with desc.object_id in the place where check body signature

@lurenpluto lurenpluto added this to the GC-supported Release milestone Apr 27, 2023
@lurenpluto
Copy link
Member Author

It was found that this mentioned solution of adding an optional field of object_id directly in ObjectMutBody has a forward compatibility problem, that is, if the new version of cyfs-base generates object.body, and the object_id field is specified, then the old version of cyfs-base will not be able to correctly decode this object (because there is no record of the actual length of the body, after the existence of unrecognized fields, can not be correctly skipped), resulting in problems

So this is a headache, in the current RawCodec system, neither desc nor body can be directly extended by fields, so consider using the following alternative:

Enable OBJECT_BODY_FLAG_EXT reserved field of body, introduce a body ext structure based on extensible encoding (such as using protobuf encoding), and put the new fields(object_id) inside, this mode can also be decoded correctly by the old version of cyfs-base

@lurenpluto lurenpluto added the Codec Encode & Decode for the Object label Apr 27, 2023
lurenpluto added a commit that referenced this issue May 19, 2023
@lurenpluto
Copy link
Member Author

In the final implementation, the ext field reserved in the last object codec refactoring is enabled, ObjectBodyExt struct is introduced, and the compatibility coding based on protobuf is adopted to deal with the subsequent demand of dynamically expanding fields and avoid the problem of inability to decode due to compatibility.

#[derive(Clone, Debug)]
pub struct ObjectBodyExt {
// The object_id of the associated desc
object_id: Option<ObjectId>,
}
impl Default for ObjectBodyExt {
fn default() -> Self {
Self { object_id: None }
}
}
impl ObjectBodyExt {
pub fn is_empty(&self) -> bool {
self.object_id.is_none()
}
}

The object body adds the corresponding methods

  • pub fn object_id(&self) -> &Option.
  • pub fn verify_object_id(&self, object_id: &ObjectId) -> BuckyResult<()>.
  • pub fn set_object_id(&mut self, object_id: Option).

AnyNamedObject also adds the corresponding methods

  • pub fn body_object_id(&self) -> &Option.
  • pub fn verify_body_object_id(&self, object_id: &ObjectId) -> BuckyResult<()>.

Also the signature verification has been improved accordingly, involving the following methods

  • pub async fn verify_object_body_sign<D, V, N>.
  • AnyNamedObjectVerifyHelper::verify_body_sign

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Any Idea Any problem/ideas/suggestions Codec Encode & Decode for the Object cyfs-base Functions and components in cyfs-base project Object Object design, codec and usage
Projects
Status: 🧪To Test
Development

When branches are created from issues, their pull requests are automatically linked.

1 participant