Example #1
0
        // Verifies the enclave report signature using the health report.
        private void VerifyEnclaveReportSignature(EnclaveReportPackage enclaveReportPackage, X509Certificate2 healthReportCert)
        {
            // Check if report is formatted correctly
            uint calculatedSize = Convert.ToUInt32(enclaveReportPackage.PackageHeader.GetSizeInPayload()) + enclaveReportPackage.PackageHeader.SignedStatementSize + enclaveReportPackage.PackageHeader.SignatureSize;

            if (calculatedSize != enclaveReportPackage.PackageHeader.PackageSize)
            {
                throw new ArgumentException(Strings.VerifyEnclaveReportFormatFailed);
            }

            using (RSA rsa = KeyConverter.GetRSAFromCertificate(healthReportCert))
            {
                if (!rsa.VerifyData(enclaveReportPackage.ReportAsBytes, enclaveReportPackage.SignatureBlob, HashAlgorithmName.SHA256, RSASignaturePadding.Pss))
                {
                    throw new ArgumentException(Strings.VerifyEnclaveReportFailed);
                }
            }
        }
        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);
        }
        // Verifies the enclave policy matches expected policy.
        private void VerifyEnclavePolicy(EnclaveReportPackage enclaveReportPackage)
        {
            EnclaveIdentity identity = enclaveReportPackage.Report.Identity;

            VerifyEnclavePolicyProperty("OwnerId", identity.OwnerId, ExpectedPolicy.OwnerId);
            VerifyEnclavePolicyProperty("AuthorId", identity.AuthorId, ExpectedPolicy.AuthorId);
            VerifyEnclavePolicyProperty("FamilyId", identity.FamilyId, ExpectedPolicy.FamilyId);
            VerifyEnclavePolicyProperty("ImageId", identity.ImageId, ExpectedPolicy.ImageId);
            VerifyEnclavePolicyProperty("EnclaveSvn", identity.EnclaveSvn, ExpectedPolicy.EnclaveSvn);
            VerifyEnclavePolicyProperty("SecureKernelSvn", identity.SecureKernelSvn, ExpectedPolicy.SecureKernelSvn);
            VerifyEnclavePolicyProperty("PlatformSvn", identity.PlatformSvn, ExpectedPolicy.PlatformSvn);

            // This is a check that the enclave is running without debug support or not.
            //
            if (identity.Flags != ExpectedPolicy.Flags)
            {
                throw new InvalidOperationException(SR.VerifyEnclaveDebuggable);
            }
        }
        // Verifies the enclave report signature using the health report.
        private void VerifyEnclaveReportSignature(EnclaveReportPackage enclaveReportPackage, X509Certificate2 healthReportCert)
        {
            // Check if report is formatted correctly
            UInt32 calculatedSize = Convert.ToUInt32(enclaveReportPackage.PackageHeader.GetSizeInPayload()) + enclaveReportPackage.PackageHeader.SignedStatementSize + enclaveReportPackage.PackageHeader.SignatureSize;

            if (calculatedSize != enclaveReportPackage.PackageHeader.PackageSize)
            {
                throw new ArgumentException(SR.VerifyEnclaveReportFormatFailed);
            }

            // IDK_S is contained in healthReport cert public key
            RSA           rsacsp    = healthReportCert.GetRSAPublicKey();
            RSAParameters rsaparams = rsacsp.ExportParameters(includePrivateParameters: false);
            RSACng        rsacng    = new RSACng();

            rsacng.ImportParameters(rsaparams);

            if (!rsacng.VerifyData(enclaveReportPackage.ReportAsBytes, enclaveReportPackage.SignatureBlob, HashAlgorithmName.SHA256, RSASignaturePadding.Pss))
            {
                throw new ArgumentException(SR.VerifyEnclaveReportFailed);
            }
        }
        // Performs Attestation per the protocol used by Virtual Secure Modules.
        private void VerifyAttestationInfo(string attestationUrl, HealthReport healthReport, EnclaveReportPackage enclaveReportPackage)
        {
            bool shouldRetryValidation;
            bool shouldForceUpdateSigningKeys = false;

            do
            {
                shouldRetryValidation = false;

                // Get HGS Root signing certs from HGS
                X509Certificate2Collection signingCerts = GetSigningCertificate(attestationUrl, shouldForceUpdateSigningKeys);

                // Verify SQL Health report root chain of trust is the HGS root signing cert
                X509ChainStatusFlags chainStatus = VerifyHealthReportAgainstRootCertificate(signingCerts, healthReport.Certificate);
                if (chainStatus != X509ChainStatusFlags.NoError)
                {
                    // In cases if we fail to validate the health report, it might be possible that we are using old signing keys
                    // let's re-download the signing keys again and re-validate the health report
                    if (!shouldForceUpdateSigningKeys)
                    {
                        shouldForceUpdateSigningKeys = true;
                        shouldRetryValidation        = true;
                    }
                    else
                    {
                        throw new AlwaysEncryptedAttestationException(String.Format(SR.VerifyHealthCertificateChainFormat, attestationUrl, chainStatus));
                    }
                }
            } while (shouldRetryValidation);

            // Verify enclave report is signed by IDK_S from health report
            VerifyEnclaveReportSignature(enclaveReportPackage, healthReport.Certificate);
        }