private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, byte[] nonce, EnclaveType enclaveType, EnclaveDiffieHellmanInfo enclaveDHInfo, ECDiffieHellman clientDHKey)
        {
            byte[] enclaveRsaPublicKey = enclavePublicKey.PublicKey;

            // For SGX enclave we Sql server sends the enclave public key XOR'ed with Nonce.
            // In case if Sql server replayed old JWT then shared secret will not match and hence client will not able to determine the updated enclave keys.
            if (enclaveType == EnclaveType.Sgx)
            {
                for (int iterator = 0; iterator < enclaveRsaPublicKey.Length; iterator++)
                {
                    enclaveRsaPublicKey[iterator] = (byte)(enclaveRsaPublicKey[iterator] ^ nonce[iterator % nonce.Length]);
                }
            }

            // Perform signature verification. The enclave's DiffieHellman public key was signed by the enclave's RSA public key.
            RSAParameters rsaParams = KeyConverter.RSAPublicKeyBlobToParams(enclaveRsaPublicKey);

            using (RSA rsa = RSA.Create(rsaParams))
            {
                if (!rsa.VerifyData(enclaveDHInfo.PublicKey, enclaveDHInfo.PublicKeySignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                {
                    throw new ArgumentException(Strings.GetSharedSecretFailed);
                }
            }

            ECParameters    ecParams     = KeyConverter.ECCPublicKeyBlobToParams(enclaveDHInfo.PublicKey);
            ECDiffieHellman enclaveDHKey = ECDiffieHellman.Create(ecParams);

            return(clientDHKey.DeriveKeyFromHash(enclaveDHKey.PublicKey, HashAlgorithmName.SHA256));
        }
Example #2
0
        private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, byte[] nonce, EnclaveType enclaveType, EnclaveDiffieHellmanInfo enclaveDHInfo, ECDiffieHellmanCng clientDHKey)
        {
            byte[] enclaveRsaPublicKey = enclavePublicKey.PublicKey;

            // For SGX enclave we Sql server sends the enclave public key XOR'ed with Nonce.
            // In case if Sql server replayed old JWT then shared secret will not match and hence client will not able to determine the updated enclave keys.
            if (enclaveType == EnclaveType.Sgx)
            {
                for (int iterator = 0; iterator < enclaveRsaPublicKey.Length; iterator++)
                {
                    enclaveRsaPublicKey[iterator] = (byte)(enclaveRsaPublicKey[iterator] ^ nonce[iterator % nonce.Length]);
                }
            }

            // Perform signature verification. The enclave's DiffieHellman public key was signed by the enclave's RSA public key.
            CngKey cngkey = CngKey.Import(enclaveRsaPublicKey, CngKeyBlobFormat.GenericPublicBlob);

            using (RSACng rsacng = new RSACng(cngkey))
            {
                if (!rsacng.VerifyData(enclaveDHInfo.PublicKey, enclaveDHInfo.PublicKeySignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                {
                    throw new ArgumentException(Strings.GetSharedSecretFailed);
                }
            }

            CngKey key = CngKey.Import(enclaveDHInfo.PublicKey, CngKeyBlobFormat.GenericPublicBlob);

            return(clientDHKey.DeriveKeyMaterial(key));
        }
Example #3
0
            public AzureAttestationInfo(byte[] attestationInfo)
            {
                try
                {
                    int offset = 0;

                    // Total size of the attestation info buffer
                    TotalSize = BitConverter.ToUInt32(attestationInfo, offset);
                    offset   += sizeof(uint);

                    // Size of the Enclave public key
                    int identitySize = BitConverter.ToInt32(attestationInfo, offset);
                    offset += sizeof(uint);

                    // Size of the Azure attestation token
                    int attestationTokenSize = BitConverter.ToInt32(attestationInfo, offset);
                    offset += sizeof(uint);

                    // Enclave type
                    int enclaveType = BitConverter.ToInt32(attestationInfo, offset);
                    EnclaveType = (EnclaveType)enclaveType;
                    offset     += sizeof(uint);

                    // Get the enclave public key
                    byte[] identityBuffer = attestationInfo.Skip(offset).Take(identitySize).ToArray();
                    Identity = new EnclavePublicKey(identityBuffer);
                    offset  += identitySize;

                    // Get Azure attestation token
                    byte[] attestationTokenBuffer = attestationInfo.Skip(offset).Take(attestationTokenSize).ToArray();
                    AttestationToken = new AzureAttestationToken(attestationTokenBuffer);
                    offset          += attestationTokenSize;

                    uint secureSessionInfoResponseSize = BitConverter.ToUInt32(attestationInfo, offset);
                    offset += sizeof(uint);

                    SessionId = BitConverter.ToInt64(attestationInfo, offset);
                    offset   += sizeof(long);

                    int    secureSessionBufferSize = Convert.ToInt32(secureSessionInfoResponseSize) - sizeof(uint);
                    byte[] secureSessionBuffer     = attestationInfo.Skip(offset).Take(secureSessionBufferSize).ToArray();
                    EnclaveDHInfo = new EnclaveDiffieHellmanInfo(secureSessionBuffer);
                    offset       += Convert.ToInt32(EnclaveDHInfo.Size);
                }
                catch (Exception exception)
                {
                    throw new AlwaysEncryptedAttestationException(String.Format(Strings.FailToParseAttestationInfo, exception.Message));
                }
            }
        // Derives the shared secret between the client and enclave.
        private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, EnclaveDiffieHellmanInfo enclaveDHInfo, ECDiffieHellmanCng clientDHKey)
        {
            // Perform signature verification. The enclave's DiffieHellman public key was signed by the enclave's RSA public key.
            CngKey cngkey = CngKey.Import(enclavePublicKey.PublicKey, CngKeyBlobFormat.GenericPublicBlob);
            RSACng rsacng = new RSACng(cngkey);

            if (!rsacng.VerifyData(enclaveDHInfo.PublicKey, enclaveDHInfo.PublicKeySignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
            {
                throw new ArgumentException(SR.GetSharedSecretFailed);
            }

            CngKey key = CngKey.Import(enclaveDHInfo.PublicKey, CngKeyBlobFormat.GenericPublicBlob);

            return(clientDHKey.DeriveKeyMaterial(key));
        }
Example #5
0
        // Derives the shared secret between the client and enclave.
        private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, EnclaveDiffieHellmanInfo enclaveDHInfo, ECDiffieHellman clientDHKey)
        {
            // Perform signature verification. The enclave's DiffieHellman public key was signed by the enclave's RSA public key.
            using (RSA rsa = KeyConverter.CreateRSAFromPublicKeyBlob(enclavePublicKey.PublicKey))
            {
                if (!rsa.VerifyData(enclaveDHInfo.PublicKey, enclaveDHInfo.PublicKeySignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                {
                    throw new ArgumentException(Strings.GetSharedSecretFailed);
                }
            }

            using (ECDiffieHellman ecdh = KeyConverter.CreateECDiffieHellmanFromPublicKeyBlob(enclaveDHInfo.PublicKey))
            {
                return(KeyConverter.DeriveKey(clientDHKey, ecdh.PublicKey));
            }
        }
        // Derives the shared secret between the client and enclave.
        private byte[] GetSharedSecret(EnclavePublicKey enclavePublicKey, EnclaveDiffieHellmanInfo enclaveDHInfo, ECDiffieHellman clientDHKey)
        {
            // Perform signature verification. The enclave's DiffieHellman public key was signed by the enclave's RSA public key.
            RSAParameters rsaParams = KeyConverter.RSAPublicKeyBlobToParams(enclavePublicKey.PublicKey);

            using (RSA rsa = RSA.Create(rsaParams))
            {
                if (!rsa.VerifyData(enclaveDHInfo.PublicKey, enclaveDHInfo.PublicKeySignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                {
                    throw new ArgumentException(Strings.GetSharedSecretFailed);
                }
            }

            ECParameters    ecParams     = KeyConverter.ECCPublicKeyBlobToParams(enclaveDHInfo.PublicKey);
            ECDiffieHellman enclaveDHKey = ECDiffieHellman.Create(ecParams);

            return(clientDHKey.DeriveKeyFromHash(enclaveDHKey.PublicKey, HashAlgorithmName.SHA256));
        }
        public AttestationInfo(byte[] attestationInfo)
        {
            int offset = 0;

            TotalSize = BitConverter.ToUInt32(attestationInfo, offset);
            offset   += sizeof(uint);

            int identitySize = BitConverter.ToInt32(attestationInfo, offset);

            offset += sizeof(uint);

            int healthReportSize = BitConverter.ToInt32(attestationInfo, offset);

            offset += sizeof(uint);

            int enclaveReportSize = BitConverter.ToInt32(attestationInfo, offset);

            offset += sizeof(uint);

            byte[] identityBuffer = attestationInfo.Skip(offset).Take(identitySize).ToArray();
            Identity = new EnclavePublicKey(identityBuffer);
            offset  += identitySize;

            byte[] healthReportBuffer = attestationInfo.Skip(offset).Take(healthReportSize).ToArray();
            HealthReport = new HealthReport(healthReportBuffer);
            offset      += healthReportSize;

            byte[] enclaveReportBuffer = attestationInfo.Skip(offset).Take(enclaveReportSize).ToArray();
            EnclaveReportPackage = new EnclaveReportPackage(enclaveReportBuffer);
            offset += EnclaveReportPackage.GetSizeInPayload();

            uint secureSessionInfoResponseSize = BitConverter.ToUInt32(attestationInfo, offset);

            offset += sizeof(uint);

            SessionId = BitConverter.ToInt64(attestationInfo, offset);
            offset   += sizeof(long);

            int secureSessionBufferSize = Convert.ToInt32(secureSessionInfoResponseSize) - sizeof(uint);

            byte[] secureSessionBuffer = attestationInfo.Skip(offset).Take(secureSessionBufferSize).ToArray();
            EnclaveDHInfo = new EnclaveDiffieHellmanInfo(secureSessionBuffer);
            offset       += Convert.ToInt32(EnclaveDHInfo.Size);
        }
Example #8
0
        private void ValidateAttestationClaims(EnclaveType enclaveType, string attestationToken, EnclavePublicKey enclavePublicKey, byte[] nonce)
        {
            // Read the json token
            JsonWebToken token = null;

            try
            {
                JsonWebTokenHandler tokenHandler = new JsonWebTokenHandler();
                token = tokenHandler.ReadJsonWebToken(attestationToken);
            }
            catch (ArgumentException argumentException)
            {
                throw new AlwaysEncryptedAttestationException(String.Format(Strings.FailToParseAttestationToken, argumentException.Message));
            }

            // Get all the claims from the token
            Dictionary <string, string> claims = new Dictionary <string, string>();

            foreach (Claim claim in token.Claims.ToList())
            {
                claims.Add(claim.Type, claim.Value);
            }

            // Get Enclave held data claim and validate it with the Base64UrlEncode(enclave public key)
            ValidateClaim(claims, "aas-ehd", enclavePublicKey.PublicKey);

            if (enclaveType == EnclaveType.Vbs)
            {
                // Get rp_data claim and validate it with the Base64UrlEncode(nonce)
                ValidateClaim(claims, "rp_data", nonce);
            }
        }
Example #9
0
        private void VerifyAzureAttestationInfo(string attestationUrl, EnclaveType enclaveType, string attestationToken, EnclavePublicKey enclavePublicKey, byte[] nonce)
        {
            bool   shouldForceUpdateSigningKeys = false;
            string attestationInstanceUrl       = GetAttestationInstanceUrl(attestationUrl);

            bool   shouldRetryValidation;
            bool   isSignatureValid;
            string exceptionMessage = string.Empty;

            do
            {
                shouldRetryValidation = false;

                // Get the OpenId config object for the signing keys
                OpenIdConnectConfiguration openIdConfig = GetOpenIdConfigForSigningKeys(attestationInstanceUrl, shouldForceUpdateSigningKeys);

                // Verify the token signature against the signing keys downloaded from meta data end point
                bool isKeySigningExpired;
                isSignatureValid = VerifyTokenSignature(attestationToken, attestationInstanceUrl, openIdConfig.SigningKeys, out isKeySigningExpired, out exceptionMessage);

                // In cases if we fail to validate the token, since we are using the old signing keys
                // let's re-download the signing keys again and re-validate the token signature
                if (!isSignatureValid && isKeySigningExpired && !shouldForceUpdateSigningKeys)
                {
                    shouldForceUpdateSigningKeys = true;
                    shouldRetryValidation        = true;
                }
            }while (shouldRetryValidation);

            if (!isSignatureValid)
            {
                throw new AlwaysEncryptedAttestationException(String.Format(Strings.AttestationTokenSignatureValidationFailed, exceptionMessage));
            }

            // Validate claims in the token
            ValidateAttestationClaims(enclaveType, attestationToken, enclavePublicKey, nonce);
        }