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

refactor!: Change MultiKeyring.children to a seq<Keyring> #223

Merged
merged 34 commits into from
Mar 10, 2020

Conversation

robin-aws
Copy link
Contributor

Resolves #222

BREAKING CHANGE: Changes the signature of constructing a MultiKeyring

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Add UTF8 encoding/decoding (#74)
First blocker: Valid() is not compilable AFAICT so you can’t test it dynamically
Deals with subtypes in externs as well (those should be forbidden by the compiler as well)
… into extern-soundness

# Conflicts:
#	src/SDK/Keyring/Defs.dfy
#	src/SDK/Keyring/KMSKeyring.dfy
#	src/SDK/Keyring/MultiKeyring.dfy
#	src/api/dotnet/Keyrings.cs
…even though it’s cheating because it can’t call Valid() in compiled code :)
Lemmas to the rescue!
… into extern-soundness

# Conflicts:
#	test/api/dotnet/ClientTests.cs
… into extern-soundness

# Conflicts:
#	test/SDK/Client.dfy
Allows the progress so far to be committed
@lavaleri
Copy link
Contributor

lavaleri commented Mar 9, 2020

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: 228a289
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

… into multi-keyring-children-as-sequence

# Conflicts:
#	src/extern/dotnet/RSAEncryption.cs
#	test/api/dotnet/ClientTests.cs
@lavaleri
Copy link
Contributor

lavaleri commented Mar 9, 2020

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: c5886e4
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@lavaleri
Copy link
Contributor

lavaleri commented Mar 9, 2020

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: 7d4d022
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@lavaleri
Copy link
Contributor

lavaleri commented Mar 9, 2020

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: 1ab23d5
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@lavaleri
Copy link
Contributor

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: d3b80e3
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@lavaleri
Copy link
Contributor

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: 8bbeb18
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@robin-aws
Copy link
Contributor Author

Note that all of the decreases * will be necessary in the next phase of things (see #166). The plan is to add support for decreases clauses that still verify a degree of non-termination while allowing external code in the control flow, but it'll take some further design to get that right. I could put all the decreases Repr clauses back until then, but honestly that's just a lie as long as we plan to allow externally-implemented Keyrings anyway. :)

var _ :- FailUnless(clientSupplier != null, "Client supplier is required");
var _ :- FailUnless(|grantTokens| <= KMSUtils.MAX_GRANT_TOKENS, "Too many grant tokens");
var keyIDsNoBlanks := Filter(keyIDs, keyID => keyID != "");
var _ :- FailUnless(forall keyID :: keyID in keyIDsNoBlanks ==> KMSUtils.ValidFormatCMK(keyID), "Invalid CMK(s)");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect that this has the potential to be an incredibly slow line. (speaking as the person who wrote ValidFormatCMK)

We should have an issue to make that function ghost, and back it with a compiled non-recursive method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually intended to delay these changes to the next PR :) I'm going to remove them from this one.

But since you mention it, it's a good point that we're going to have a lot of lurking performance issues as we add more dynamic execution of requirements. I mentioned to Rustan that we could really use tail recursion for functions, so hopefully we could tackle it that way. I worry more about stack overflow errors than performance personally.

if |generator| == 0 {
generatorOption := None;
} else {
var _ :- FailUnless(KMSUtils.ValidFormatCMK(generator), "Invalid generator CMK(s)");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one generator CMK, also it would be nice to include the invalid string in the error message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above, will move to the next PR and fix there.

var _ :- FailUnless(KMSUtils.ValidFormatCMK(generator), "Invalid generator CMK(s)");
generatorOption := Some(generator);
}
var _ :- FailUnless(forall grantToken :: grantToken in grantTokens ==> 0 < |grantToken| <= 8192, "Invalid grant token(s)");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bounds for the GrantToken type were written before we standardized on the Valid() ValidWitness() pattern. It should be brought inline with the new pattern, instead of using the raw integer here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above, will move to the next PR and fix there.

}
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, punting this to the next PR anyway

private static string SUCCESS = "SUCCESS";

// MakeKMSKeyring is a helper method that creates a KMS Keyring for unit testing
private Keyring MakeKMSKeyring()
private Keyring MakeKMSKeyring()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace

Copy link
Contributor

@lavaleri lavaleri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP: I can't find any spec that states what "chore" means, so I personally would go with refactor here.

I'd like to understand the implications behind the changes a little bit better to make sure that we aren't going through any one way doors here.

@@ -55,6 +55,7 @@ module {:extern "DefaultCMMDef"} DefaultCMMDef {
case None => true
case Some(sigType) =>
res.value.signingKey.Some?
decreases *
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add TODO here too

Is there an issue for the dafny change to prove some termination? Is there any corresponding issue esdk side?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will definitely be an issue, yes. On sober second thought I'm going to delay these changes as well so they're in context for why we need them.

@@ -10,8 +10,8 @@ module {:extern "KeyringDefs"} KeyringDefs {
import AlgorithmSuite

trait {:termination false} Keyring {
ghost var Repr : set<object>
predicate Valid() reads this, Repr
ghost const Repr : set<object>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this requiring that all implemented keyrings not maintain any changeable state? And if so, doesn't that limit the range of behavior that the spec currently allows in Keyrings? e.g. There could be some user out there that has already created their own keyring in Java/Python/JS that won't be able to create their keyring in C#.

Why is this change necessary? I'm guessing it's needed to prove something about the Multikeyring, but maybe we need to examine what the implication of that proof is, and how important it actually is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more related to the next change, which provides a way for the control flow from external code to ensure that any object is ever Valid(). I think I will again punt this to the next change for better context.

It doesn't mean no changeable state at all, but it does mean no change in the set of objects that make up Repr. So a Keyring could certainly have some fields that are allowed to change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, I'm still concerned about how that might limit behavior, but we can discuss that in the next PR.

@@ -109,6 +135,7 @@ module {:extern "KMSKeyringDef"} KMSKeyringDef {
&& materials.encryptedDataKeys <= res.value.encryptedDataKeys
&& materials.signingKey == res.value.signingKey
ensures isDiscovery ==> res.Success? && res.value == materials
decreases Repr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this not needed before but is needed now?

ensures Valid()
{
generator := g;
children := c;
Repr := {this} + (if g != null then {g} + g.Repr else {}) + {children} + childrenRepr(c[..]);
Repr := {this} + (if g != null then {g} + g.Repr else {}) + childrenRepr(c);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove {children}? Is there anything other than idiom that enforces that Repr contains this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because children is now a sequence and therefore not an object, so it can't be part of Repr any more! :)

Comment on lines 10 to 12
using byteseq = Dafny.Sequence<byte>;
using icharseq = Dafny.ISequence<char>;
using charseq = Dafny.Sequence<char>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove byteseq and charseq here and in other files (unless I missed somewhere where they are still used)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - annoying that Rider doesn't seem to detect unused usings :)

@@ -18,6 +18,8 @@ module {:extern "STL"} StandardLibrary {
}
}

method {:extern} As<T>(x: object) returns (r: Option<T>)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be added as part of this PR? I don't see where it is currently used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, removing

@@ -131,6 +131,13 @@ module {:extern "Materials"} Materials {

type ValidEncryptionMaterials = i: EncryptionMaterials | i.Valid() witness EncryptionMaterials.ValidWitness()

class {:extern} ExternalEncryptionMaterials {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, why is this added in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another accidentally change along for the ride, removing

@robin-aws robin-aws changed the title chore!: Change MultiKeyring.children to a seq<Keyring> refactor!: Change MultiKeyring.children to a seq<Keyring> Mar 10, 2020
@lavaleri
Copy link
Contributor

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: 359a8d8
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@lavaleri
Copy link
Contributor

AWS CodeBuild CI Report

  • CodeBuild project: DafnyESDK
  • Commit ID: f802648
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@robin-aws
Copy link
Contributor Author

Apologies for the messy PR - I didn't look closely enough at what I'd failed to remove. :)

Copy link
Contributor

@lavaleri lavaleri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@robin-aws robin-aws merged commit 3c0df96 into aws:develop Mar 10, 2020
@robin-aws robin-aws deleted the multi-keyring-children-as-sequence branch March 10, 2020 22:17
josecorella added a commit to josecorella/aws-encryption-sdk-dafny that referenced this pull request Oct 11, 2023
…ws#223)

Co-authored-by: lavaleri <49660121+lavaleri@users.noreply.github.com>
Co-authored-by: seebees <ryanemer@amazon.com>
josecorella added a commit that referenced this pull request Oct 11, 2023
…223)

Co-authored-by: lavaleri <49660121+lavaleri@users.noreply.github.com>
Co-authored-by: seebees <ryanemer@amazon.com>
josecorella added a commit that referenced this pull request Oct 11, 2023
…223)

Co-authored-by: lavaleri <49660121+lavaleri@users.noreply.github.com>
Co-authored-by: seebees <ryanemer@amazon.com>
josecorella added a commit that referenced this pull request Oct 11, 2023
…223)

Co-authored-by: lavaleri <49660121+lavaleri@users.noreply.github.com>
Co-authored-by: seebees <ryanemer@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switch MultiKeyring.children from an array to a sequence
3 participants