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

abe: Improve test clarity #393

Merged
merged 1 commit into from Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 0 additions & 26 deletions abe/cpabe/tkn20/testdata/policies

This file was deleted.

71 changes: 71 additions & 0 deletions abe/cpabe/tkn20/testdata/policies.json
@@ -0,0 +1,71 @@
[
{
"policy": "region: US",
"success": false,
"attributes": {
"region": "EU"
}
},
{
"policy": "not region: US",
"success": true,
"attributes": {
"region": "EU"
}
},
{
"policy": "region: US or region: EU or tier: 1 or tier: 2 or tier: 3 and owner: cloudflare",
"success": true,
"attributes": {
"region": "AZ",
"tier": "2",
"owner": "cloudflare"
}
},
{
"policy": "(region: US or region: EU) or (tier: 1 or tier: 2 or tier: 3) and (owner: cloudflare)",
"success": true,
"attributes": {
"region": "AZ",
"tier": "1",
"owner": "cloudflare"
}
},
{
"policy": "((region: US or region: EU) and (not (tier: 3)))",
"success": true,
"attributes": {
"region": "EU",
"tier": "2",
"owner": "cloudflare"
}
},
{
"policy": "not (region: US or region: EU)",
"success": false,
"attributes": {
"region": "EU"
}
},
{
"policy": "not not region: US",
"success": false,
"attributes": {
"region": "EU"
}
},
{
"policy": "region: US or region: US",
"success": false,
"attributes": {
"region": "AZ"
}
},
{
"policy": "region: US and region: EU or region: ASIA",
"success": false,
"attributes": {
"region": "US"
}
}
]
102 changes: 38 additions & 64 deletions abe/cpabe/tkn20/tkn20_test.go
@@ -1,81 +1,52 @@
package tkn20

import (
"bufio"
"bytes"
"crypto/rand"
"encoding/json"
"fmt"
"os"
"testing"

"github.com/cloudflare/circl/abe/cpabe/tkn20/internal/dsl"
"github.com/cloudflare/circl/abe/cpabe/tkn20/internal/tkn"
)

type TestAttribute struct {
Fail bool // if this test case should fail
Attrs map[string]string `json:"attributes"`
type TestCase struct {
Policy string
Success bool
Attrs map[string]string `json:"attributes"`
}

func loadTestCases(t *testing.T) ([]Policy, []TestAttribute, []Attributes) {
testFile, err := os.Open("testdata/policies")
func TestConcurrentDecryption(t *testing.T) {
var tests []TestCase
buf, _ := os.ReadFile("testdata/policies.json")
err := json.Unmarshal(buf, &tests)
if err != nil {
t.Fatal(err)
}
defer testFile.Close()

scanner := bufio.NewScanner(testFile)
var policies []Policy
var testAttrs []TestAttribute
i := 0
for scanner.Scan() {
if i%3 == 0 {
p := Policy{}
err := p.FromString(scanner.Text())
if err != nil {
t.Fatal(err)
}
policies = append(policies, p)
} else if i%3 == 1 {
testAttrs = append(testAttrs, parseTestAttr(t, scanner.Text()))
}
i++
}

attrs := make([]Attributes, len(testAttrs))
for i, testAttr := range testAttrs {
currAttrMap := make(map[string]tkn.Attribute, len(testAttr.Attrs))
for k, v := range testAttr.Attrs {
currAttrMap[k] = tkn.Attribute{
Value: tkn.HashStringToScalar(dsl.AttrHashKey, v),
}
}
attrs[i] = Attributes{currAttrMap}
}
return policies, testAttrs, attrs
}

func TestConcurrentDecryption(t *testing.T) {
policies, testAttrs, attrs := loadTestCases(t)
msg := []byte("must have the precious")
for i, policy := range policies {
for i, test := range tests {
t.Run(fmt.Sprintf("TestConcurrentDecryption:#%d", i), func(t *testing.T) {
pk, msk, err := Setup(rand.Reader)
if err != nil {
t.Fatal(err)
}
policy := Policy{}
err = policy.FromString(test.Policy)
if err != nil {
t.Fatal(err)
}
ct, err := pk.Encrypt(rand.Reader, policy, msg)
if err != nil {
t.Fatalf("encryption failed: %s", err)
}
sk, err := msk.KeyGen(rand.Reader, attrs[i])
attrs := Attributes{}
attrs.FromMap(test.Attrs)
sk, err := msk.KeyGen(rand.Reader, attrs)
if err != nil {
t.Fatalf("key generation failed: %s", err)
}
checkResults := func(ct []byte, sk AttributeKey, i int) {
pt, err := sk.Decrypt(ct)
if !testAttrs[i].Fail {
if tests[i].Success {
if err != nil {
t.Errorf("decryption failed: %s", err)
}
Expand All @@ -95,19 +66,31 @@ func TestConcurrentDecryption(t *testing.T) {
}

func TestEndToEndEncryption(t *testing.T) {
policies, testAttrs, attrs := loadTestCases(t)
var tests []TestCase
buf, _ := os.ReadFile("testdata/policies.json")
err := json.Unmarshal(buf, &tests)
if err != nil {
t.Fatal(err)
}
msg := []byte("must have the precious")
for i, policy := range policies {
for i, test := range tests {
t.Run(fmt.Sprintf("TestEndToEndEncryption:#%d", i), func(t *testing.T) {
pk, msk, err := Setup(rand.Reader)
if err != nil {
t.Fatal(err)
}
policy := Policy{}
err = policy.FromString(test.Policy)
if err != nil {
t.Fatal(err)
}
ct, err := pk.Encrypt(rand.Reader, policy, msg)
if err != nil {
t.Fatalf("encryption failed: %s", err)
}
sk, err := msk.KeyGen(rand.Reader, attrs[i])
attrs := Attributes{}
attrs.FromMap(test.Attrs)
sk, err := msk.KeyGen(rand.Reader, attrs)
if err != nil {
t.Fatalf("key generation failed: %s", err)
}
Expand All @@ -120,16 +103,16 @@ func TestEndToEndEncryption(t *testing.T) {
if err = npol2.FromString(strpol); err != nil {
t.Fatalf("string %s didn't parse: %s", strpol, err)
}
sat := policy.Satisfaction(attrs[i])
if sat != npol.Satisfaction(attrs[i]) {
sat := policy.Satisfaction(attrs)
if sat != npol.Satisfaction(attrs) {
t.Fatalf("extracted policy doesn't match original")
}
if sat != npol2.Satisfaction(attrs[i]) {
if sat != npol2.Satisfaction(attrs) {
t.Fatalf("round triped policy doesn't match original")
}
ctSat := attrs[i].CouldDecrypt(ct)
ctSat := attrs.CouldDecrypt(ct)
pt, err := sk.Decrypt(ct)
if !testAttrs[i].Fail {
if test.Success {
// test case should succeed
if !sat {
t.Fatalf("satisfaction failed")
Expand Down Expand Up @@ -250,12 +233,3 @@ func TestPolicyMethods(t *testing.T) {
}
}
}

func parseTestAttr(t *testing.T, buf string) TestAttribute {
var testAttr TestAttribute
err := json.Unmarshal([]byte("{"+buf+"}"), &testAttr)
if err != nil {
t.Fatalf("invalid attributes %s, parse error: %s\n", buf, err)
}
return testAttr
}