1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.adservices.adselection; 18 19 import static com.android.adservices.data.adselection.EncryptionKeyConstants.EncryptionKeyType.ENCRYPTION_KEY_TYPE_AUCTION; 20 21 import com.android.adservices.data.adselection.DBEncryptionKey; 22 import com.android.adservices.data.adselection.DBProtectedServersEncryptionConfig; 23 import com.android.adservices.service.common.httpclient.AdServicesHttpClientResponse; 24 25 import com.google.auto.value.AutoValue; 26 import com.google.common.collect.ImmutableMap; 27 28 import org.json.JSONArray; 29 import org.json.JSONException; 30 import org.json.JSONObject; 31 32 import java.util.List; 33 34 public class AuctionEncryptionKeyFixture { 35 public static final Long DEFAULT_MAX_AGE_SECONDS = 604800L; 36 public static final String DEFAULT_MAX_AGE = "max-age=" + DEFAULT_MAX_AGE_SECONDS; 37 public static final String DEFAULT_CACHED_AGE = "800"; 38 private static final Long EXPIRY_TTL_1SEC = 1L; 39 private static final String CACHE_CONTROL_HEADER_LABEL = "cache-control"; 40 private static final String CACHED_AGE_HEADER_LABEL = "age"; 41 42 private static final String KEY_ID_LABEL = "id"; 43 private static final String PUBLIC_KEY_LABEL = "key"; 44 public static final String COORDINATOR_URL_AUCTION = "https://example-auction.com/full/url"; 45 public static final String COORDINATOR_URL_AUCTION_ORIGIN = "https://example-auction.com"; 46 public static final DBEncryptionKey ENCRYPTION_KEY_AUCTION = 47 DBEncryptionKey.builder() 48 .setKeyIdentifier("152233fc-f255-4c3d-b3ef-7e2b7fbb9ca7") 49 .setPublicKey("3QKut1VYAJGrE3TTu4NGZq3sPSgAeRaaTIdi7eZqtwk=") 50 .setEncryptionKeyType(ENCRYPTION_KEY_TYPE_AUCTION) 51 .setExpiryTtlSeconds(1000L) 52 .build(); 53 public static final DBEncryptionKey ENCRYPTION_KEY_AUCTION_TTL_1SECS = 54 DBEncryptionKey.builder() 55 .setKeyIdentifier("1b333681-4fe3-4ba9-b603-5169d421734c") 56 .setPublicKey("nD4MogDIKg+NIXiJ3lEPHcf8mYOl1wjioNFe6h9pUAI=") 57 .setEncryptionKeyType(ENCRYPTION_KEY_TYPE_AUCTION) 58 .setExpiryTtlSeconds(EXPIRY_TTL_1SEC) 59 .build(); 60 public static final ImmutableMap<String, List<String>> DEFAULT_RESPONSE_HEADERS = 61 ImmutableMap.of( 62 CACHE_CONTROL_HEADER_LABEL, 63 List.of(DEFAULT_MAX_AGE), 64 CACHED_AGE_HEADER_LABEL, 65 List.of(DEFAULT_CACHED_AGE)); 66 public static final AuctionKey AUCTION_KEY_1 = 67 AuctionKey.builder() 68 .setKeyId("152233fc-f255-4c3d-b3ef-7e2b7fbb9ca7") 69 .setPublicKey("3QKut1VYAJGrE3TTu4NGZq3sPSgAeRaaTIdi7eZqtwk=") 70 .build(); 71 public static final AuctionKey AUCTION_KEY_2 = 72 AuctionKey.builder() 73 .setKeyId("1b333681-4fe3-4ba9-b603-5169d421734c") 74 .setPublicKey("nD4MogDIKg+NIXiJ3lEPHcf8mYOl1wjioNFe6h9pUAI=") 75 .build(); 76 private static final AuctionKey AUCTION_KEY_3 = 77 AuctionKey.builder() 78 .setKeyId("420ec4eb-8753-4c45-88b9-7917baecbd21") 79 .setPublicKey("KROE/B6FBOV2+6coHHtpGi1Gxoi+bOh9srrBP64JPBk") 80 .build(); 81 private static final AuctionKey AUCTION_KEY_4 = 82 AuctionKey.builder() 83 .setKeyId("49b4de4f-4c9e-4285-afa0-78c3baea13b3") 84 .setPublicKey("7tabvCt19oMF5Quu4cAQetS6xlLFkjIbcY6330+cjlo=") 85 .build(); 86 private static final AuctionKey AUCTION_KEY_5 = 87 AuctionKey.builder() 88 .setKeyId("7b6724dc-839c-4108-bfa7-2e73eb19e5fe") 89 .setPublicKey("t/dzKzHJKe7k//n2u7wDdvxRtgXy9SncfXz6g8JB/m4=") 90 .build(); 91 92 public static final DBProtectedServersEncryptionConfig ENCRYPTION_KEY_AUCTION_WITH_COORDINATOR = 93 DBProtectedServersEncryptionConfig.builder() 94 .setKeyIdentifier(AUCTION_KEY_2.keyId()) 95 .setPublicKey(AUCTION_KEY_2.publicKey()) 96 .setEncryptionKeyType(ENCRYPTION_KEY_TYPE_AUCTION) 97 .setExpiryTtlSeconds(1000L) 98 .setCoordinatorUrl(COORDINATOR_URL_AUCTION) 99 .build(); 100 getAuctionResponseBodySingleKey()101 public static String getAuctionResponseBodySingleKey() throws JSONException { 102 JSONObject json = new JSONObject(); 103 json.put("keys", new JSONArray().put(getAuctionKeyJson(AUCTION_KEY_1))); 104 return json.toString(); 105 } 106 mockAuctionKeyFetchResponse()107 public static AdServicesHttpClientResponse mockAuctionKeyFetchResponse() throws JSONException { 108 return AdServicesHttpClientResponse.builder() 109 .setResponseBody(getDefaultAuctionResponseBody()) 110 .setResponseHeaders(DEFAULT_RESPONSE_HEADERS) 111 .build(); 112 } 113 mockAuctionKeyFetchResponseWithOneKey()114 public static AdServicesHttpClientResponse mockAuctionKeyFetchResponseWithOneKey() 115 throws JSONException { 116 return AdServicesHttpClientResponse.builder() 117 .setResponseBody(getDefaultAuctionResponseBodyWithOneKey()) 118 .setResponseHeaders(DEFAULT_RESPONSE_HEADERS) 119 .build(); 120 } 121 122 /** Gets the AdServicesHttpClientResponse with the provided AuctionKey */ mockAuctionKeyFetchResponseWithGivenKey( AuctionKey auctionKey)123 public static AdServicesHttpClientResponse mockAuctionKeyFetchResponseWithGivenKey( 124 AuctionKey auctionKey) throws JSONException { 125 return AdServicesHttpClientResponse.builder() 126 .setResponseBody(getDeterministicAuctionResponseBody(auctionKey)) 127 .setResponseHeaders(DEFAULT_RESPONSE_HEADERS) 128 .build(); 129 } 130 getAuctionKeyJson(AuctionKey key)131 private static JSONObject getAuctionKeyJson(AuctionKey key) throws JSONException { 132 return new JSONObject() 133 .put(KEY_ID_LABEL, key.keyId()) 134 .put(PUBLIC_KEY_LABEL, key.publicKey()); 135 } 136 getDefaultAuctionResponseBody()137 private static String getDefaultAuctionResponseBody() throws JSONException { 138 JSONObject json = new JSONObject(); 139 json.put( 140 "keys", 141 new JSONArray() 142 .put(getAuctionKeyJson(AUCTION_KEY_1)) 143 .put(getAuctionKeyJson(AUCTION_KEY_2)) 144 .put(getAuctionKeyJson(AUCTION_KEY_3)) 145 .put(getAuctionKeyJson(AUCTION_KEY_4)) 146 .put(getAuctionKeyJson(AUCTION_KEY_5))); 147 return json.toString(); 148 } 149 getDeterministicAuctionResponseBody(AuctionKey auctionKey)150 private static String getDeterministicAuctionResponseBody(AuctionKey auctionKey) 151 throws JSONException { 152 JSONObject json = new JSONObject(); 153 json.put("keys", new JSONArray().put(getAuctionKeyJson(auctionKey))); 154 return json.toString(); 155 } 156 getDefaultAuctionResponseBodyWithOneKey()157 private static String getDefaultAuctionResponseBodyWithOneKey() throws JSONException { 158 JSONObject json = new JSONObject(); 159 json.put("keys", new JSONArray().put(getAuctionKeyJson(AUCTION_KEY_1))); 160 return json.toString(); 161 } 162 163 @AutoValue 164 public abstract static class AuctionKey { keyId()165 public abstract String keyId(); 166 publicKey()167 public abstract String publicKey(); 168 builder()169 public static AuctionKey.Builder builder() { 170 return new AutoValue_AuctionEncryptionKeyFixture_AuctionKey.Builder(); 171 } 172 173 @AutoValue.Builder 174 public abstract static class Builder { setKeyId(String keyId)175 public abstract Builder setKeyId(String keyId); 176 setPublicKey(String publicKey)177 public abstract Builder setPublicKey(String publicKey); 178 build()179 public abstract AuctionKey build(); 180 } 181 } 182 } 183