public void ValidateTokenCallback() { // Create a JWT whose body will become valid 5 seconds from now. object tokenBody = new JwtTestBody { StringField = "Foo", NotBefore = DateTimeOffset.Now.AddSeconds(5).ToUnixTimeSeconds(), ExpiresAt = DateTimeOffset.Now.AddSeconds(60).ToUnixTimeSeconds(), }; X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; AsymmetricAlgorithm privateKey = TestEnvironment.PolicyManagementKey; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody), new AttestationTokenSigningKey(privateKey, fullCertificate)); string serializedToken = token.Serialize(); var validationOptions = new AttestationTokenValidationOptions(); validationOptions.TokenValidated += (args) => { Assert.AreEqual(1, args.Signer.SigningCertificates.Count); Assert.IsNotNull(args.Signer.SigningCertificates[0]); CollectionAssert.AreEqual(fullCertificate.Export(X509ContentType.Cert), args.Signer.SigningCertificates[0].Export(X509ContentType.Cert)); Assert.AreEqual(fullCertificate, args.Signer.SigningCertificates[0]); return(Task.CompletedTask); }; // ValidateTokenAsync will throw an exception if a callback is specified outside of an attestation client. // Note that validation callbacks are tested elsewhere in the AttestationClient codebase. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken( serializedToken, tokenBody, validationOptions)); }
public async Task SetPolicySecured(AttestationAdministrationClient adminClient, bool isIsolated) { // Reset the current attestation policy to a known state. Necessary if there were previous runs that failed. await ResetAttestationPolicy(adminClient, AttestationType.OpenEnclave, true, isIsolated); string originalPolicy = await adminClient.GetPolicyAsync(AttestationType.OpenEnclave); X509Certificate2 x509Certificate; RSA rsaKey; if (isIsolated) { x509Certificate = TestEnvironment.PolicyManagementCertificate; rsaKey = TestEnvironment.PolicyManagementKey; } else { x509Certificate = TestEnvironment.PolicyCertificate0; rsaKey = TestEnvironment.PolicySigningKey0; } byte[] disallowDebuggingHash; { var policySetResult = await adminClient.SetPolicyAsync(AttestationType.OpenEnclave, disallowDebugging, new TokenSigningKey(rsaKey, x509Certificate)); var shaHasher = SHA256Managed.Create(); var policySetToken = new AttestationToken( new StoredAttestationPolicy { AttestationPolicy = disallowDebugging }, new TokenSigningKey(rsaKey, x509Certificate)); disallowDebuggingHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.ToString())); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Updated, policySetResult.Value.PolicyResolution); CollectionAssert.AreEqual(disallowDebuggingHash, policySetResult.Value.PolicyTokenHash); Assert.AreEqual(x509Certificate, policySetResult.Value.PolicySigner.SigningCertificates[0]); } { var policyResult = await adminClient.GetPolicyAsync(AttestationType.OpenEnclave); Assert.AreEqual(disallowDebugging, policyResult.Value); } { var policySetResult = await adminClient.ResetPolicyAsync(AttestationType.OpenEnclave, new TokenSigningKey(rsaKey, x509Certificate)); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Removed, policySetResult.Value.PolicyResolution); } { var policyResult = await adminClient.GetPolicyAsync(AttestationType.OpenEnclave); // And when we're done, policy should be reset to the original value. Assert.AreEqual(originalPolicy, policyResult.Value); } }
public async Task ValidateTokenCallback() { // Create a JWT whose body will become valid 5 seconds from now. object tokenBody = new JwtTestBody { StringField = "Foo", NotBefore = DateTimeOffset.Now.AddSeconds(5).ToUnixTimeSeconds(), ExpiresAt = DateTimeOffset.Now.AddSeconds(60).ToUnixTimeSeconds(), }; X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; AsymmetricAlgorithm privateKey = TestEnvironment.PolicyManagementKey; var token = new AttestationToken(tokenBody, new TokenSigningKey(privateKey, fullCertificate)); string serializedToken = token.ToString(); // This check should fail since the token won't be valid for another 5 seconds. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken(serializedToken, tokenBody)); // This check should succeed since the token slack is greater than the 10 seconds before it becomes valid. await ValidateSerializedToken( serializedToken, tokenBody, new TokenValidationOptions(timeValidationSlack : 10, validationCallback : (AttestationToken tokenToValidate, AttestationSigner tokenSigner) => { Assert.AreEqual(1, tokenSigner.SigningCertificates.Count); Assert.IsNotNull(tokenSigner.SigningCertificates[0]); CollectionAssert.AreEqual(fullCertificate.Export(X509ContentType.Cert), tokenSigner.SigningCertificates[0].Export(X509ContentType.Cert)); Assert.AreEqual(fullCertificate, tokenSigner.SigningCertificates[0]); return(true); })); }
public static bool ValidateMaaJwt(string attestDnsName, AttestationToken token, AttestationSigner signer, bool includeDetails) { var tenantName = attestDnsName.Split('.')[0]; var attestUri = new Uri($"https://{attestDnsName}"); AttestationResult result = token.GetBody <AttestationResult>(); ValidateJwtIssuerIsTenant(result, attestUri, includeDetails); ValidateSigningCertIssuerMatchesJwtIssuer(result, signer, includeDetails); X509Certificate2 signingCertificate = signer.SigningCertificates[0]; byte[] certificateBytes = signingCertificate.RawData; string x5c = Convert.ToBase64String(certificateBytes); #if LOG_BOUNCY_CASTLE if (includeDetails) { var bouncyCertParser = new X509CertificateParser(); var bouncyCert = bouncyCertParser.ReadCertificate(certificateBytes); var bouncyAsn1Sequence = (DerSequence)bouncyCert.CertificateStructure.ToAsn1Object(); for (int i = 0; i < bouncyAsn1Sequence.Count; i++) { var asn1 = bouncyAsn1Sequence[i]; Logger.WriteLine(53, 128, $"{asn1.GetType().ToString(),50} : ", BitConverter.ToString(asn1.GetEncoded()).Replace("-", "")); } } #endif Logger.WriteBanner("VALIDATING MAA JWT TOKEN - MAA EMBEDDED QUOTE IN SIGNING CERTIFICATE FOR JWT"); MaaQuoteValidator.ValidateMaaQuote(x5c, includeDetails); return(true); }
public async Task GetUnsecuredAttestationToken() { object tokenBody = new StoredAttestationPolicy { AttestationPolicy = "Foo", }; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody)); string serializedToken = token.Serialize(); await ValidateSerializedToken(serializedToken, tokenBody); }
public async Task GetUnsecuredAttestationToken() { object tokenBody = new StoredAttestationPolicy { AttestationPolicy = "Foo", }; var token = new AttestationToken(tokenBody); string serializedToken = token.ToString(); await ValidateSerializedToken(serializedToken, tokenBody); }
/// <summary> /// Ensure that the serialized token validates correctly. /// </summary> /// <param name="serializedToken"></param> public async Task ValidateSerializedToken(string serializedToken, object expectedBody, AttestationTokenValidationOptions tokenOptions = default) { var parsedToken = AttestationToken.Deserialize(serializedToken); await Task.Yield(); Assert.IsTrue(await parsedToken.ValidateTokenAsync(tokenOptions ?? new AttestationTokenValidationOptions { ValidateExpirationTime = true }, null)); // The body of the token should match the expected body. Assert.AreEqual(JsonSerializer.Serialize(expectedBody), Encoding.UTF8.GetString(parsedToken.TokenBodyBytes.ToArray())); }
public static bool ValidateMaaJwt(string attestDnsName, AttestationToken serviceToken, AttestationSigner tokenSigner, bool includeDetails) { var tenantName = attestDnsName.Split('.')[0]; var attestUri = new Uri($"https://{attestDnsName}"); AttestationResult result = serviceToken.GetBody <AttestationResult>(); ValidateJwtIssuerIsTenant(result, attestUri, includeDetails); ValidateSigningCertIssuerMatchesJwtIssuer(result, tokenSigner, includeDetails); return(true); }
public async Task SettingAttestationPolicy() { var endpoint = TestEnvironment.AadAttestationUrl; #region Snippet:GetPolicy var client = new AttestationAdministrationClient(new Uri(endpoint), new DefaultAzureCredential()); var policyResult = await client.GetPolicyAsync(AttestationType.SgxEnclave); var result = policyResult.Value; #endregion #region Snippet:SetPolicy string attestationPolicy = "version=1.0; authorizationrules{=> permit();}; issuancerules{};"; //@@ X509Certificate2 policyTokenCertificate = new X509Certificate2(<Attestation Policy Signing Certificate>); //@@ AsymmetricAlgorithm policyTokenKey = <Attestation Policy Signing Key>; /*@@*/ var policyTokenCertificate = TestEnvironment.PolicyCertificate0; /*@@*/ var policyTokenKey = TestEnvironment.PolicySigningKey0; var setResult = client.SetPolicy(AttestationType.SgxEnclave, attestationPolicy, new TokenSigningKey(policyTokenKey, policyTokenCertificate)); #endregion #region Snippet:VerifySigningHash // The SetPolicyAsync API will create an AttestationToken signed with the TokenSigningKey to transmit the policy. // To verify that the policy specified by the caller was received by the service inside the enclave, we // verify that the hash of the policy document returned from the Attestation Service matches the hash // of an attestation token created locally. //@@ TokenSigningKey signingKey = new TokenSigningKey(<Customer provided signing key>, <Customer provided certificate>) /*@@*/ TokenSigningKey signingKey = new TokenSigningKey(policyTokenKey, policyTokenCertificate); var policySetToken = new AttestationToken( new StoredAttestationPolicy { AttestationPolicy = attestationPolicy }, signingKey); using var shaHasher = SHA256Managed.Create(); var attestationPolicyHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.ToString())); Debug.Assert(attestationPolicyHash.SequenceEqual(setResult.Value.PolicyTokenHash)); #endregion var resetResult = client.ResetPolicy(AttestationType.SgxEnclave); // When the attestation instance is in Isolated mode, the ResetPolicy API requires using a signing key/certificate to authorize the user. var resetResult2 = client.ResetPolicy( AttestationType.SgxEnclave, new TokenSigningKey(TestEnvironment.PolicySigningKey0, policyTokenCertificate)); return; }
public async Task GetSecuredAttestationToken() { X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; AsymmetricAlgorithm privateKey = TestEnvironment.PolicyManagementKey; object tokenBody = new StoredAttestationPolicy { AttestationPolicy = "Foo", }; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody), new AttestationTokenSigningKey(privateKey, fullCertificate)); string serializedToken = token.Serialize(); await ValidateSerializedToken(serializedToken, tokenBody); }
public async Task SetPolicyUnsecuredAad() { var adminclient = TestEnvironment.GetAadAdministrationClient(this); // Reset the current attestation policy to a known state. Necessary if there were previous runs that failed. await ResetAttestationPolicy(adminclient, AttestationType.OpenEnclave, false, false); string originalPolicy; { originalPolicy = await adminclient.GetPolicyAsync(AttestationType.OpenEnclave); } byte[] disallowDebuggingHash; { var policySetResult = await adminclient.SetPolicyAsync(AttestationType.OpenEnclave, disallowDebugging); // The SetPolicyAsync API will create an UnsecuredAttestationToken to transmit the policy. var shaHasher = SHA256Managed.Create(); var policySetToken = new AttestationToken(new StoredAttestationPolicy { AttestationPolicy = disallowDebugging }); disallowDebuggingHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.ToString())); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Updated, policySetResult.Value.PolicyResolution); CollectionAssert.AreEqual(disallowDebuggingHash, policySetResult.Value.PolicyTokenHash); } { string policyResult = await adminclient.GetPolicyAsync(AttestationType.OpenEnclave); Assert.AreEqual(disallowDebugging, policyResult); } { var policySetResult = await adminclient.ResetPolicyAsync(AttestationType.OpenEnclave); Assert.AreEqual(200, policySetResult.GetRawResponse().Status); Assert.AreEqual(PolicyModification.Removed, policySetResult.Value.PolicyResolution); } { var policyResult = await adminclient.GetPolicyAsync(AttestationType.OpenEnclave); // And when we're done, policy should be reset to the original value. Assert.AreEqual(originalPolicy, policyResult.Value); } }
public async Task GetSecuredAttestationTokenWithPrivateKey() { X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; fullCertificate.PrivateKey = TestEnvironment.PolicyManagementKey; // The body of attestation token MUST be a JSON object. TestBody body = new TestBody { StringField = "Foo", }; var token = new AttestationToken(BinaryData.FromObjectAsJson(body), new AttestationTokenSigningKey(fullCertificate)); string serializedToken = token.Serialize(); await ValidateSerializedToken(serializedToken, body); }
public async Task ValidateJustExpiredAttestationToken() { // Create a JWT whose body has just expired. object tokenBody = new JwtTestBody { StringField = "Foo", ExpiresAt = DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(5)).ToUnixTimeSeconds(), }; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody)); string serializedToken = token.Serialize(); // This check should fail since the token expired 5 seconds ago. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken(serializedToken, tokenBody)); // This check should succeed since the token slack is greater than the 5 second expiration time. await ValidateSerializedToken(serializedToken, tokenBody, new AttestationTokenValidationOptions { TimeValidationSlack = 10 }); }
public async Task ValidateTooEarlyAttestationToken() { // Create a JWT whose body will become valid 5 seconds from now. object tokenBody = new JwtTestBody { StringField = "Foo", NotBefore = DateTimeOffset.Now.AddSeconds(5).ToUnixTimeSeconds(), ExpiresAt = DateTimeOffset.Now.AddSeconds(60).ToUnixTimeSeconds(), }; X509Certificate2 fullCertificate = TestEnvironment.PolicyManagementCertificate; AsymmetricAlgorithm privateKey = TestEnvironment.PolicyManagementKey; var token = new AttestationToken(BinaryData.FromObjectAsJson(tokenBody), new AttestationTokenSigningKey(privateKey, fullCertificate)); string serializedToken = token.Serialize(); // This check should fail since the token won't be valid for another 5 seconds. Assert.ThrowsAsync(typeof(Exception), async() => await ValidateSerializedToken(serializedToken, tokenBody)); // This check should succeed since the token slack is greater than the 10 seconds before it becomes valid. await ValidateSerializedToken(serializedToken, tokenBody, new AttestationTokenValidationOptions { TimeValidationSlack = 10 }); }
private BinaryData SendTokenToRelyingParty(AttestationToken token) { return(null); }