// When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache. internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter) { ////for simulator: enclave does not send public key, and sends an empty attestation info //// The only non-trivial content it sends is the session setup info (DH pubkey of enclave) sqlEnclaveSession = null; counter = 0; try { ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString()); sqlEnclaveSession = GetEnclaveSessionFromCache(enclaveSessionParameters, out counter); if (sqlEnclaveSession == null) { if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl)) { ////Read AttestationInfo int attestationInfoOffset = 0; uint sizeOfTrustedModuleAttestationInfoBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); attestationInfoOffset += sizeof(UInt32); int sizeOfTrustedModuleAttestationInfoBufferInt = checked ((int)sizeOfTrustedModuleAttestationInfoBuffer); Debug.Assert(sizeOfTrustedModuleAttestationInfoBuffer == 0); ////read secure session info uint sizeOfSecureSessionInfoResponse = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); attestationInfoOffset += sizeof(UInt32); byte[] enclaveSessionHandle = new byte[EnclaveSessionHandleSize]; Buffer.BlockCopy(attestationInfo, attestationInfoOffset, enclaveSessionHandle, 0, EnclaveSessionHandleSize); attestationInfoOffset += EnclaveSessionHandleSize; uint sizeOfTrustedModuleDHPublicKeyBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); attestationInfoOffset += sizeof(UInt32); uint sizeOfTrustedModuleDHPublicKeySignatureBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset); attestationInfoOffset += sizeof(UInt32); int sizeOfTrustedModuleDHPublicKeyBufferInt = checked ((int)sizeOfTrustedModuleDHPublicKeyBuffer); byte[] trustedModuleDHPublicKey = new byte[sizeOfTrustedModuleDHPublicKeyBuffer]; Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKey, 0, sizeOfTrustedModuleDHPublicKeyBufferInt); attestationInfoOffset += sizeOfTrustedModuleDHPublicKeyBufferInt; byte[] trustedModuleDHPublicKeySignature = new byte[sizeOfTrustedModuleDHPublicKeySignatureBuffer]; Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKeySignature, 0, checked ((int)sizeOfTrustedModuleDHPublicKeySignatureBuffer)); byte[] sharedSecret; using ECDiffieHellman ecdh = KeyConverter.CreateECDiffieHellmanFromPublicKeyBlob(trustedModuleDHPublicKey); sharedSecret = KeyConverter.DeriveKey(clientDHKey, ecdh.PublicKey); long sessionId = BitConverter.ToInt64(enclaveSessionHandle, 0); sqlEnclaveSession = AddEnclaveSessionToCache(enclaveSessionParameters, sharedSecret, sessionId, out counter); } else { throw new AlwaysEncryptedAttestationException(Strings.FailToCreateEnclaveSession); } } } finally { UpdateEnclaveSessionLockStatus(sqlEnclaveSession); } }
// Gets the information that SqlClient subsequently uses to initiate the process of attesting the enclave and to establish a secure session with the enclave. internal override SqlEnclaveAttestationParameters GetAttestationParameters(string attestationUrl, byte[] customData, int customDataLength) { ECDiffieHellman clientDHKey = KeyConverter.CreateECDiffieHellman(DiffieHellmanKeySize); return(new SqlEnclaveAttestationParameters(VsmHGSProtocolId, new byte[] { }, clientDHKey)); }