Skip to content

Commit 2050f4b

Browse files
committed
Add tests for invalid keys from upstream, and rename test cases.
Change-Id: Ib41cb81c779534fc6efd74d66bf4728efd743906
1 parent b31bb8c commit 2050f4b

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed

cab-token-generator/java/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactory.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ private byte[] serializeCredentialAccessBoundary(
486486
.setAvailableResource(rule.getAvailableResource());
487487

488488
// Availability condition is an optional field from the CredentialAccessBoundary
489+
// CEL compliation is only performed if there is a non-empty availablity condition.
489490
if (rule.getAvailabilityCondition() != null) {
490491
String availabilityCondition =
491492
rule.getAvailabilityCondition().getExpression();
@@ -522,6 +523,8 @@ private byte[] encryptRestrictions(byte[] restriction, String sessionKey) throws
522523
Aead aead =
523524
keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class);
524525

526+
// For Client-Side CAB token encryption, empty associated data is expected.
527+
// Tink requires a byte[0] to be passed for this case.
525528
return aead.encrypt(restriction, /*associatedData=*/new byte[0]);
526529
}
527530

cab-token-generator/javatests/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactoryTest.java

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import dev.cel.expr.Expr;
6767

6868
import java.io.IOException;
69+
import java.security.GeneralSecurityException;
6970
import java.time.Duration;
7071
import java.util.Base64;
7172
import java.util.Map;
@@ -589,7 +590,7 @@ private static void triggerConcurrentRefresh(
589590
}
590591

591592
@Test
592-
public void generateToken() throws Exception {
593+
public void generateToken_withAvailablityCondition_success() throws Exception {
593594
MockStsTransportFactory transportFactory = new MockStsTransportFactory();
594595
transportFactory.transport.setReturnAccessBoundarySessionKey(true);
595596

@@ -662,7 +663,7 @@ public void generateToken() throws Exception {
662663
}
663664

664665
@Test
665-
public void generateToken_withoutAvailabilityCondition() throws Exception {
666+
public void generateToken_withoutAvailabilityCondition_success() throws Exception {
666667
MockStsTransportFactory transportFactory = new MockStsTransportFactory();
667668
transportFactory.transport.setReturnAccessBoundarySessionKey(true);
668669

@@ -719,7 +720,7 @@ public void generateToken_withoutAvailabilityCondition() throws Exception {
719720
}
720721

721722
@Test
722-
public void generateToken_withInvalidCelExpression() throws Exception {
723+
public void generateToken_withInvalidAvailabilityCondition_failure() throws Exception {
723724
MockStsTransportFactory transportFactory = new MockStsTransportFactory();
724725
transportFactory.transport.setReturnAccessBoundarySessionKey(true);
725726

@@ -756,4 +757,84 @@ public void generateToken_withInvalidCelExpression() throws Exception {
756757
assertThrows(CelValidationException.class,
757758
() -> { factory.generateToken(accessBoundary); });
758759
}
760+
761+
@Test
762+
public void generateToken_withSessionKeyNotBase64Encoded_failure() throws Exception {
763+
MockStsTransportFactory transportFactory = new MockStsTransportFactory();
764+
transportFactory.transport.setReturnAccessBoundarySessionKey(true);
765+
transportFactory.transport.setAccessBoundarySessionKey("invalid_key");
766+
767+
ClientSideCredentialAccessBoundaryFactory.Builder builder =
768+
ClientSideCredentialAccessBoundaryFactory.newBuilder();
769+
770+
ClientSideCredentialAccessBoundaryFactory factory =
771+
builder
772+
.setSourceCredential(getServiceAccountSourceCredentials(
773+
mockTokenServerTransportFactory))
774+
.setHttpTransportFactory(transportFactory)
775+
.build();
776+
777+
CredentialAccessBoundary.Builder cabBuilder =
778+
CredentialAccessBoundary.newBuilder();
779+
CredentialAccessBoundary accessBoundary =
780+
cabBuilder
781+
.addRule(
782+
CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
783+
.setAvailableResource("//storage.googleapis.com/projects/"
784+
+ "_/buckets/example-bucket")
785+
.setAvailablePermissions(
786+
ImmutableList.of("inRole:roles/storage.objectViewer"))
787+
.setAvailabilityCondition(
788+
CredentialAccessBoundary.AccessBoundaryRule
789+
.AvailabilityCondition.newBuilder()
790+
.setExpression(
791+
"resource.name.startsWith('projects/_/"
792+
+ "buckets/example-bucket/objects/customer-a')")
793+
.build())
794+
.build())
795+
.build();
796+
797+
assertThrows(IllegalArgumentException.class,
798+
() -> { factory.generateToken(accessBoundary); });
799+
}
800+
801+
@Test
802+
public void generateToken_withMalformSessionKey_failure() throws Exception {
803+
MockStsTransportFactory transportFactory = new MockStsTransportFactory();
804+
transportFactory.transport.setReturnAccessBoundarySessionKey(true);
805+
transportFactory.transport.setAccessBoundarySessionKey("aW52YWxpZF9rZXk=");
806+
807+
ClientSideCredentialAccessBoundaryFactory.Builder builder =
808+
ClientSideCredentialAccessBoundaryFactory.newBuilder();
809+
810+
ClientSideCredentialAccessBoundaryFactory factory =
811+
builder
812+
.setSourceCredential(getServiceAccountSourceCredentials(
813+
mockTokenServerTransportFactory))
814+
.setHttpTransportFactory(transportFactory)
815+
.build();
816+
817+
CredentialAccessBoundary.Builder cabBuilder =
818+
CredentialAccessBoundary.newBuilder();
819+
CredentialAccessBoundary accessBoundary =
820+
cabBuilder
821+
.addRule(
822+
CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
823+
.setAvailableResource("//storage.googleapis.com/projects/"
824+
+ "_/buckets/example-bucket")
825+
.setAvailablePermissions(
826+
ImmutableList.of("inRole:roles/storage.objectViewer"))
827+
.setAvailabilityCondition(
828+
CredentialAccessBoundary.AccessBoundaryRule
829+
.AvailabilityCondition.newBuilder()
830+
.setExpression(
831+
"resource.name.startsWith('projects/_/"
832+
+ "buckets/example-bucket/objects/customer-a')")
833+
.build())
834+
.build())
835+
.build();
836+
837+
assertThrows(GeneralSecurityException.class,
838+
() -> { factory.generateToken(accessBoundary); });
839+
}
759840
}

oauth2_http/javatests/com/google/auth/oauth2/MockStsTransport.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public final class MockStsTransport extends MockHttpTransport {
7676

7777
private boolean returnExpiresIn = true;
7878
private boolean returnAccessBoundarySessionKey = false;
79+
private String accessBoundarySessionKey = ACCESS_BOUNDARY_SESSION_KEY_VALUE;
7980
private MockLowLevelHttpRequest request;
8081
private int requestCount = 0;
8182

@@ -142,7 +143,7 @@ public LowLevelHttpResponse execute() throws IOException {
142143
}
143144

144145
if (returnAccessBoundarySessionKey) {
145-
response.put("access_boundary_session_key", ACCESS_BOUNDARY_SESSION_KEY_VALUE);
146+
response.put("access_boundary_session_key", accessBoundarySessionKey);
146147
}
147148

148149
return new MockLowLevelHttpResponse()
@@ -189,6 +190,10 @@ public void setReturnExpiresIn(boolean returnExpiresIn) {
189190
this.returnExpiresIn = returnExpiresIn;
190191
}
191192

193+
public void setAccessBoundarySessionKey(String accessBoundarySessionKey) {
194+
this.accessBoundarySessionKey = accessBoundarySessionKey;
195+
}
196+
192197
public void setReturnAccessBoundarySessionKey(boolean returnAccessBoundarySessionKey) {
193198
this.returnAccessBoundarySessionKey = returnAccessBoundarySessionKey;
194199
}

0 commit comments

Comments
 (0)