Skip to content

Commit 66a49d7

Browse files
authored
Merge pull request #15 from IABTechLab/jon-UID2-1266-consistent-token-prefixes
jon2-UID2-1266-consistent-token-prefixes
2 parents 479bbc8 + 9fb878e commit 66a49d7

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed

UID2.Client.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package>
33
<metadata>
44
<id>UID2.Client</id>
5-
<version>5.1.2</version>
5+
<version>5.1.3</version>
66
<title>UID2 Client C# SDK</title>
77
<authors>UID2 team</authors>
88
<owners>UID2 team</owners>

src/UID2.Client/UID2Client.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public async Task<RefreshResponse> RefreshAsync(CancellationToken token)
124124

125125
private string GetAssemblyNameAndVersion()
126126
{
127-
var version = "5.1.2";
127+
var version = "5.1.3";
128128
return "uid-client-net-" + version;
129129
}
130130

@@ -163,4 +163,4 @@ private async Task<RefreshResponse> RefreshInternal(CancellationToken token)
163163
}
164164
}
165165
}
166-
}
166+
}

src/UID2.Client/Utils/UID2TokenGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ private static string GenerateUid2TokenWithDebugInfo(string uid, Key masterKey,
145145
var firstChar = uid.Substring(0, 1);
146146
var identityType = (firstChar == "F" || firstChar == "B") ? IdentityType.Phone : IdentityType.Email; //see UID2-79+Token+and+ID+format+v3
147147

148-
rootStreamWriter.Write((byte)((encryptParams.IdentityScope << 4) | ((int)identityType << 2)));
148+
rootStreamWriter.Write((byte)((encryptParams.IdentityScope << 4) | ((int)identityType << 2) | 3));
149149
rootStreamWriter.Write((byte)adTokenVersion);
150150
rootStreamWriter.Write((int)masterKey.Id);
151151

@@ -209,4 +209,4 @@ private static byte[] EncryptGCM(byte[] data, byte[] iv, byte[] secret)
209209
return cipherText;
210210
}
211211
}
212-
}
212+
}

test/UID2.Client.Test/EncryptionTestsV4.cs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void crossPlatformConsistencyCheck_Base64UrlTestCases()
4040

4141
}
4242

43-
public void crossPlatformConsistencyCheck_Base64UrlTest(byte[] rawInput, String expectedBase64URLStr)
43+
public void crossPlatformConsistencyCheck_Base64UrlTest(byte[] rawInput, string expectedBase64URLStr)
4444
{
4545
var stream = new MemoryStream();
4646
var writer = new BigEndianByteWriter(stream);
@@ -65,7 +65,7 @@ public void crossPlatformConsistencyCheck_Base64UrlTest(byte[] rawInput, String
6565
[Fact]
6666
public void crossPlatformConsistencyCheck_Decrypt()
6767
{
68-
String crossPlatformAdvertisingToken =
68+
string crossPlatformAdvertisingToken =
6969
"AIAAAACkOqJj9VoxXJNnuX3v-ymceRf8_Av0vA5asOj9YBZJc1kV1vHdmb0AIjlzWnFF-gxIlgXqhRFhPo3iXpugPBl3gv4GKnGkw-Zgm2QqMsDPPLpMCYiWrIUqHPm8hQiq9PuTU-Ba9xecRsSIAN0WCwKLwA_EDVdzmnLJu64dQoeYmuu3u1G2EuTkuMrevmP98tJqSUePKwnfK73-0Zdshw";
7070
//Sunday, 1 January 2023 1:01:01 AM UTC
7171
var referenceTimestampMs = 1672534861000L;
@@ -93,8 +93,8 @@ public void crossPlatformConsistencyCheck_Decrypt()
9393
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
9494

9595
//verify that the dynamically created ad token can be decrypted
96-
String runtimeAdvertisingToken =
97-
UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, masterKey, SITE_ID, siteKey, encryptParams);
96+
string runtimeAdvertisingToken =
97+
GenerateUid2TokenV4(EXAMPLE_UID, masterKey, SITE_ID, siteKey, encryptParams);
9898
//best effort check as the token might simply just not require padding
9999
Assert.Equal(-1, runtimeAdvertisingToken.IndexOf('='));
100100

@@ -107,14 +107,38 @@ public void crossPlatformConsistencyCheck_Decrypt()
107107
res = client.Decrypt(crossPlatformAdvertisingToken, NOW);
108108
Assert.Equal(EXAMPLE_UID, res.Uid);
109109
}
110+
111+
private static void ValidateAdvertisingToken(string advertisingTokenString, IdentityScope identityScope, IdentityType identityType) {
112+
string firstChar = advertisingTokenString.Substring(0, 1);
113+
if (identityScope == IdentityScope.UID2)
114+
Assert.Equal(identityType == IdentityType.Email ? "A" : "B", firstChar);
115+
else
116+
Assert.Equal(identityType == IdentityType.Email ? "E" : "F", firstChar);
117+
118+
string secondChar = advertisingTokenString.Substring(1, 1);
119+
Assert.Equal("4", secondChar);
120+
121+
//No URL-unfriendly characters allowed:
122+
Assert.Equal(-1, advertisingTokenString.IndexOf('='));
123+
Assert.Equal(-1, advertisingTokenString.IndexOf('+'));
124+
Assert.Equal(-1, advertisingTokenString.IndexOf('/'));
125+
}
126+
127+
private static string GenerateUid2TokenV4(string uid, Key masterKey, int siteId, Key siteKey, UID2TokenGenerator.Params tokenGeneratorParams)
128+
{
129+
string advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(uid, masterKey, siteId, siteKey, tokenGeneratorParams);
130+
ValidateAdvertisingToken(advertisingToken, IdentityScope.UID2, IdentityType.Email);
131+
return advertisingToken;
132+
}
133+
110134

111135
[Fact]
112136
public void SmokeTest()
113137
{
114138
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
115139
var refreshResult = client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
116140
Assert.True(refreshResult.Success);
117-
string advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
141+
string advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
118142
var res = client.Decrypt(advertisingToken, NOW);
119143
Assert.True(res.Success);
120144
Assert.Equal(EXAMPLE_UID, res.Uid);
@@ -124,7 +148,7 @@ public void SmokeTest()
124148
public void EmptyKeyContainer()
125149
{
126150
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
127-
var advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
151+
var advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
128152
var res = client.Decrypt(advertisingToken, NOW);
129153
Assert.False(res.Success);
130154
Assert.Equal(DecryptionStatus.NotInitialized, res.Status);
@@ -134,7 +158,7 @@ public void EmptyKeyContainer()
134158
public void ExpiredKeyContainer()
135159
{
136160
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
137-
var advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
161+
var advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
138162

139163
Key masterKeyExpired = new Key(MASTER_KEY_ID, -1, NOW, NOW.AddHours(-2), NOW.AddHours(-1), MASTER_SECRET);
140164
Key siteKeyExpired = new Key(SITE_KEY_ID, SITE_ID, NOW, NOW.AddHours(-2), NOW.AddHours(-1), SITE_SECRET);
@@ -149,7 +173,7 @@ public void ExpiredKeyContainer()
149173
public void NotAuthorizedForMasterKey()
150174
{
151175
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
152-
var advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
176+
var advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
153177

154178
Key anotherMasterKey = new Key(MASTER_KEY_ID + SITE_KEY_ID + 1, -1, NOW, NOW, NOW.AddHours(1), MASTER_SECRET);
155179
Key anotherSiteKey = new Key(MASTER_KEY_ID + SITE_KEY_ID + 2, SITE_ID, NOW, NOW, NOW.AddHours(1), SITE_SECRET);
@@ -163,7 +187,7 @@ public void NotAuthorizedForMasterKey()
163187
public void InvalidPayload()
164188
{
165189
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
166-
byte[] payload = UID2Base64UrlCoder.Decode(UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams));
190+
byte[] payload = UID2Base64UrlCoder.Decode(GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams));
167191
var advertisingToken = UID2Base64UrlCoder.Encode(payload.SkipLast(1).ToArray());
168192

169193
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
@@ -180,7 +204,7 @@ public void TokenExpiryAndCustomNow()
180204

181205
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
182206
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
183-
var advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, encryptParams);
207+
var advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, encryptParams);
184208

185209
var res = client.Decrypt(advertisingToken, expiry.AddSeconds(1));
186210
Assert.Equal(DecryptionStatus.ExpiredToken, res.Status);
@@ -195,7 +219,7 @@ public void EncryptDataSiteIdFromToken()
195219
byte[] data = { 1, 2, 3, 4, 5, 6 };
196220
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
197221
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
198-
string advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
222+
string advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
199223
var encrypted = client.EncryptData(EncryptionDataRequest.ForData(data).WithAdvertisingToken(advertisingToken));
200224
Assert.Equal(EncryptionStatus.Success, encrypted.Status);
201225
var decrypted = client.DecryptData(encrypted.EncryptedData);
@@ -209,7 +233,7 @@ public void EncryptDataSiteIdFromTokenCustomSiteKeySiteId()
209233
byte[] data = { 1, 2, 3, 4, 5, 6 };
210234
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
211235
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
212-
string advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID2, SITE_KEY, UID2TokenGenerator.DefaultParams);
236+
string advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID2, SITE_KEY, UID2TokenGenerator.DefaultParams);
213237
var encrypted = client.EncryptData(EncryptionDataRequest.ForData(data).WithAdvertisingToken(advertisingToken));
214238
Assert.Equal(EncryptionStatus.Success, encrypted.Status);
215239
var decrypted = client.DecryptData(encrypted.EncryptedData);
@@ -223,7 +247,7 @@ public void EncryptDataSiteIdAndTokenSet()
223247
byte[] data = { 1, 2, 3, 4, 5, 6 };
224248
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
225249
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
226-
var advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
250+
var advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, UID2TokenGenerator.DefaultParams);
227251
Assert.Throws<ArgumentException>(() =>
228252
client.EncryptData(EncryptionDataRequest.ForData(data).WithAdvertisingToken(advertisingToken).WithSiteId(SITE_KEY.SiteId)));
229253
}
@@ -235,7 +259,7 @@ public void EncryptDataTokenDecryptKeyExpired()
235259
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
236260
Key key = new Key(SITE_KEY_ID, SITE_ID2, NOW, NOW, NOW.AddDays(-1), MakeTestSecret(9));
237261
client.RefreshJson(KeySetToJson(MASTER_KEY, key));
238-
string advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, key, UID2TokenGenerator.DefaultParams);
262+
string advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, key, UID2TokenGenerator.DefaultParams);
239263
var encrypted = client.EncryptData(EncryptionDataRequest.ForData(data).WithAdvertisingToken(advertisingToken));
240264
Assert.Equal(EncryptionStatus.NotAuthorizedForKey, encrypted.Status);
241265
}
@@ -249,7 +273,7 @@ public void EncryptDataTokenExpired()
249273
byte[] data = { 1, 2, 3, 4, 5, 6 };
250274
var client = new UID2Client("ep", "ak", CLIENT_SECRET, IdentityScope.UID2);
251275
client.RefreshJson(KeySetToJson(MASTER_KEY, SITE_KEY));
252-
var advertisingToken = UID2TokenGenerator.GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, encryptParams);
276+
var advertisingToken = GenerateUid2TokenV4(EXAMPLE_UID, MASTER_KEY, SITE_ID, SITE_KEY, encryptParams);
253277
var encrypted = client.EncryptData(EncryptionDataRequest.ForData(data).WithAdvertisingToken(advertisingToken));
254278
Assert.Equal(EncryptionStatus.TokenDecryptFailure, encrypted.Status);
255279

0 commit comments

Comments
 (0)