-
Notifications
You must be signed in to change notification settings - Fork 95
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
Provide builder for KBS Protocol Wrapper #278
Provide builder for KBS Protocol Wrapper #278
Conversation
b1d98aa
to
e6e878a
Compare
http_client: reqwest::Client, | ||
authenticated: bool, | ||
} | ||
|
||
struct NoTee; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we use generic types here? I saw builder in projects like reqwest
and in-toto
uses the following, which seems more straightforward
pub struct KbsProtocolWrapperBuilder {
tee: Option<..>,
}
impl KbsProtocolWrapperBuilder {
pub fn with_tee(mut self, tee: ..) -> Self {
self.tee = Some(tee);
self
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we use generic types here? I saw builder in projects like
reqwest
andin-toto
uses the following, which seems more straightforwardpub struct KbsProtocolWrapperBuilder { tee: Option<..>, } impl KbsProtocolWrapperBuilder { pub fn with_tee(mut self, tee: ..) -> Self { self.tee = Some(tee); self } }
Yeah, this is a more pragmatic way to create builders. If you call .build()
and the builder struct has Option<...>
types, you need to perform runtime checks to verify tee
is actually set (e.g. return Result<KbsProtocolWrapper>
or panic even).
If you use encode the requirements via generics the verification happens at compile time, you are not able to call build()
unless you called .with_tee()
.
The type-level verification is admittedly more verbose, and I just noticed we already need to return a Result<KbsProtocolWrapper>
from .build()
, so i'd be fine with changing this to a builder w/ Option<...>
properties. What do you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic types actually will save runtime. I'm ok with both. However there is a naive question from myside. I think the main aim of the PR is to avoid creating an Attester from the TEE detection heuristic
inside new()
of KbsProtocolWrapper
, but to receive an outer Attester
parameter. If so, why do not directly add a function with the signature
pub fn new(attester: BoxedAttester) -> Self {
Self {
attester,
...
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic types actually will save runtime. I'm ok with both. However there is a naive question from myside. I think the main aim of the PR is to avoid
creating an Attester from the TEE detection heuristic
insidenew()
ofKbsProtocolWrapper
, but to receive an outerAttester
parameter. If so, why do not directly add a function with the signaturepub fn new(attester: BoxedAttester) -> Self { Self { attester, ... } }
you mean pub fn new_with_attester()
or simply replacing the existing pub fn new()
function?
if we can do that, the builder pattern is too much. it would maybe be useful if we would want to inject an HTTP client (for unit testing or having a generic RPC client), but we can also add it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. cc @jialez0 please take a look if it is ok to you
e6e878a
to
bff7053
Compare
Hi @mkulke Can you rebase the PR? |
Signed-off-by: Magnus Kulke <magnuskulke@microsoft.com>
Signed-off-by: Magnus Kulke <magnuskulke@microsoft.com>
59fcb52
to
b401624
Compare
@mkulke Well. Seems that some coupled code was broken by this PR, s.t. |
oh, that's a surprise. i'll look into that. |
Signed-off-by: Magnus Kulke <magnuskulke@microsoft.com>
Ok, apparently those unit tests construct a kbs protocol wrapper w/ an The tests in question are URI parsing tests however, so they don't mind a non-functional kbc client. Refactoring the tests/code to untangle uri parsing from the kbc client and unit testing just that is probably the right fix long-term. The unit tests atm perform IO side-effects as they detect the tee which adds delay and faux errors to the log. Short term I see 2 ways to address that:
I don't particularly like either option, but restoring the |
I am missing something at the high level. When would we want to use an Attester other than the one that we would currently create with the TEE detection heuristic? |
One scenario would be a kbs-client which is not able to access the TEE's evidence-retrieval facilities directly (like in peer-pods where the network is segmented), without having to replicate the kbs client logic. Another scenario would be the injection of a mock attester in a unit test for the RCAR logic. |
Currently
KbsProtocolWrapper
bootstraps itself. It detects a TEE and attempts to create an Attester object. There are situations in which it is desirable to inject an Attester implementation from the caller side (e.g. we want to wrapget_evidence()
for a given TEE in an IPC call).(discussion here, for more context)
This is made possible by providing a builder for the wrapper. Existing code should work without modifications. The builder requires a tee and accepts an attester object optionally.
There are some drive-by fixes, as the type
KBSProtocolWrapper
currently doesn't reflect certain invariants:nonce
should not default to an empty string, we want to bail out if it's unsetattester andtee_key
otoh shouldn't be wrapped in Options, the wrapper will not work w/o them.tee_key
can be passed by ref