コード例 #1
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);
            }
        }
コード例 #2
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);
        }
コード例 #3
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));
        }
コード例 #4
0
ファイル: EnclaveApi.cs プロジェクト: zuozhu315/Vanara
 public static extern bool IsEnclaveTypeSupported(EnclaveType flEnclaveType);
コード例 #5
0
ファイル: EnclaveApi.cs プロジェクト: zuozhu315/Vanara
 public static extern void CreateEnclave(HPROCESS hProcess, IntPtr lpAddress, SizeT dwSize, SizeT dwInitialCommittment, EnclaveType flEnclaveType, IntPtr lpEnclaveInformation, uint dwInfoLength, out uint lpEnclaveError);
コード例 #6
0
        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));
        }
コード例 #7
0
ファイル: EnclaveApi.cs プロジェクト: sasqwatch/Vanara
 public static extern SafeEnclaveHandle CreateEnclave(HPROCESS hProcess, IntPtr lpAddress, SizeT dwSize, SizeT dwInitialCommittment, EnclaveType flEnclaveType, in ENCLAVE_CREATE_INFO_SGX lpEnclaveInformation, uint dwInfoLength, out uint lpEnclaveError);