public bool GetXvcKeyByGuid(Guid keyGuid, out byte[] keyOutput) { keyOutput = null; if (XvcInfo.EncryptionKeyIds == null || XvcInfo.EncryptionKeyIds.Length < 1 || XvcInfo.KeyCount == 0) { return(false); } bool keyFound = false; foreach (var xvcKey in XvcInfo.EncryptionKeyIds) { if (new Guid(xvcKey.KeyId) == keyGuid) { keyFound = true; } } if (!keyFound) { Console.WriteLine($"Key {keyGuid} is not used by this XVC"); return(false); } if (DurangoKeys.IsCikLoaded(keyGuid)) { keyOutput = DurangoKeys.GetCikByGuid(keyGuid).KeyData; return(true); } Console.WriteLine($"Did not find CIK {keyGuid} loaded in Keystorage"); Console.WriteLine("Checking for XML licenses..."); string licenseFolder = Path.GetDirectoryName(FilePath); if (Path.GetFileName(licenseFolder) == "MSXC") { licenseFolder = Path.GetDirectoryName(licenseFolder); } if (String.IsNullOrEmpty(licenseFolder)) { return(false); } licenseFolder = Path.Combine(licenseFolder, "Licenses"); if (!Directory.Exists(licenseFolder)) { return(false); } foreach (string file in Directory.GetFiles(licenseFolder, "*.xml")) { var xml = new XmlDocument(); xml.Load(file); var xmlns = new XmlNamespaceManager(xml.NameTable); xmlns.AddNamespace("resp", "http://schemas.microsoft.com/xboxlive/security/clas/LicResp/v1"); XmlNode licenseNode = xml.SelectSingleNode("//resp:SignedLicense", xmlns); if (licenseNode == null) { continue; } string signedLicense = licenseNode.InnerText; byte[] signedLicenseBytes = Convert.FromBase64String(signedLicense); var licenseXml = new XmlDocument(); licenseXml.LoadXml(Encoding.ASCII.GetString(signedLicenseBytes)); var xmlns2 = new XmlNamespaceManager(licenseXml.NameTable); xmlns2.AddNamespace("resp", "http://schemas.microsoft.com/xboxlive/security/clas/LicResp/v1"); XmlNode keyIdNode = licenseXml.SelectSingleNode("//resp:KeyId", xmlns2); if (keyIdNode == null) { continue; } if (keyGuid != new Guid(keyIdNode.InnerText)) { continue; } XmlNode licenseBlockNode = licenseXml.SelectSingleNode("//resp:SPLicenseBlock", xmlns2); if (licenseBlockNode == null) { continue; } string licenseBlock = licenseBlockNode.InnerText; byte[] licenseBlockBytes = Convert.FromBase64String(licenseBlock); var block = new XvcLicenseBlock(licenseBlockBytes); var keyIdBlock = block.GetBlockWithId(XvcLicenseBlockId.KeyId); if (keyIdBlock == null) { continue; } if (!(new Guid(keyIdBlock.BlockData) == keyGuid)) { continue; } var decryptKeyBlock = block.GetBlockWithId(XvcLicenseBlockId.EncryptedCik); if (decryptKeyBlock == null) { continue; } keyOutput = decryptKeyBlock.BlockData; Console.WriteLine($"Xvd CIK key found in {file}"); // todo: decrypt/deobfuscate the key return(true); } return(false); }
public string GetXvcKey(int keyIndex, out byte[] keyOutput) { keyOutput = null; if (XvcInfo.EncryptionKeyIds == null || XvcInfo.EncryptionKeyIds.Length <= keyIndex || XvcInfo.KeyCount == 0 || XvcInfo.EncryptionKeyIds[keyIndex].IsKeyNulled) return null; var keyGuid = new Guid(XvcInfo.EncryptionKeyIds[keyIndex].KeyId); if (XvcInfo.IsUsingTestCik && keyGuid == GetTestCikKey()) { keyOutput = CikKeys[keyGuid]; return "testsigned"; } if (CikKeys.ContainsKey(keyGuid)) { keyOutput = CikKeys[keyGuid]; return keyGuid.ToString() + " (from cik_keys.bin)"; } string licenseFolder = Path.GetDirectoryName(FilePath); if (Path.GetFileName(licenseFolder) == "MSXC") licenseFolder = Path.GetDirectoryName(licenseFolder); if (String.IsNullOrEmpty(licenseFolder)) return null; // fix for weird resharper warning licenseFolder = Path.Combine(licenseFolder, "Licenses"); if (!Directory.Exists(licenseFolder)) return null; foreach (string file in Directory.GetFiles(licenseFolder, "*.xml")) { var xml = new XmlDocument(); xml.Load(file); var xmlns = new XmlNamespaceManager(xml.NameTable); xmlns.AddNamespace("resp", "http://schemas.microsoft.com/xboxlive/security/clas/LicResp/v1"); XmlNode licenseNode = xml.SelectSingleNode("//resp:SignedLicense", xmlns); if (licenseNode == null) continue; string signedLicense = licenseNode.InnerText; byte[] signedLicenseBytes = Convert.FromBase64String(signedLicense); var licenseXml = new XmlDocument(); licenseXml.LoadXml(Encoding.ASCII.GetString(signedLicenseBytes)); var xmlns2 = new XmlNamespaceManager(licenseXml.NameTable); xmlns2.AddNamespace("resp", "http://schemas.microsoft.com/xboxlive/security/clas/LicResp/v1"); XmlNode keyIdNode = licenseXml.SelectSingleNode("//resp:KeyId", xmlns2); if (keyIdNode == null) continue; string keyId = keyIdNode.InnerText; if (keyId != keyGuid.ToString()) continue; XmlNode licenseBlockNode = licenseXml.SelectSingleNode("//resp:SPLicenseBlock", xmlns2); if (licenseBlockNode == null) continue; string licenseBlock = licenseBlockNode.InnerText; byte[] licenseBlockBytes = Convert.FromBase64String(licenseBlock); var block = new XvcLicenseBlock(licenseBlockBytes); var keyIdBlock = block.GetBlockWithId(XvcLicenseBlockId.KeyId); if (keyIdBlock == null) continue; if (!keyIdBlock.BlockData.IsEqualTo(XvcInfo.EncryptionKeyIds[keyIndex].KeyId)) continue; var decryptKeyBlock = block.GetBlockWithId(XvcLicenseBlockId.EncryptedCik); if (decryptKeyBlock == null) continue; keyOutput = decryptKeyBlock.BlockData; // todo: decrypt/deobfuscate the key return file; } return null; }
public string GetXvcKey(int keyIndex, out byte[] keyOutput) { keyOutput = null; if (XvcInfo.EncryptionKeyIds == null || XvcInfo.EncryptionKeyIds.Length <= keyIndex || XvcInfo.KeyCount == 0 || XvcInfo.EncryptionKeyIds[keyIndex].IsKeyNulled) { return(null); } var keyGuid = new Guid(XvcInfo.EncryptionKeyIds[keyIndex].KeyId); if (XvcInfo.IsUsingTestCik && keyGuid == GetTestCikKey()) { keyOutput = CikKeys[keyGuid]; return("testsigned"); } if (CikKeys.ContainsKey(keyGuid)) { keyOutput = CikKeys[keyGuid]; return(keyGuid.ToString() + " (from cik_keys.bin)"); } string licenseFolder = Path.GetDirectoryName(FilePath); if (Path.GetFileName(licenseFolder) == "MSXC") { licenseFolder = Path.GetDirectoryName(licenseFolder); } if (String.IsNullOrEmpty(licenseFolder)) { return(null); // fix for weird resharper warning } licenseFolder = Path.Combine(licenseFolder, "Licenses"); if (!Directory.Exists(licenseFolder)) { return(null); } foreach (string file in Directory.GetFiles(licenseFolder, "*.xml")) { var xml = new XmlDocument(); xml.Load(file); var xmlns = new XmlNamespaceManager(xml.NameTable); xmlns.AddNamespace("resp", "http://schemas.microsoft.com/xboxlive/security/clas/LicResp/v1"); XmlNode licenseNode = xml.SelectSingleNode("//resp:SignedLicense", xmlns); if (licenseNode == null) { continue; } string signedLicense = licenseNode.InnerText; byte[] signedLicenseBytes = Convert.FromBase64String(signedLicense); var licenseXml = new XmlDocument(); licenseXml.LoadXml(Encoding.ASCII.GetString(signedLicenseBytes)); var xmlns2 = new XmlNamespaceManager(licenseXml.NameTable); xmlns2.AddNamespace("resp", "http://schemas.microsoft.com/xboxlive/security/clas/LicResp/v1"); XmlNode keyIdNode = licenseXml.SelectSingleNode("//resp:KeyId", xmlns2); if (keyIdNode == null) { continue; } string keyId = keyIdNode.InnerText; if (keyId != keyGuid.ToString()) { continue; } XmlNode licenseBlockNode = licenseXml.SelectSingleNode("//resp:SPLicenseBlock", xmlns2); if (licenseBlockNode == null) { continue; } string licenseBlock = licenseBlockNode.InnerText; byte[] licenseBlockBytes = Convert.FromBase64String(licenseBlock); var block = new XvcLicenseBlock(licenseBlockBytes); var keyIdBlock = block.GetBlockWithId(XvcLicenseBlockId.KeyId); if (keyIdBlock == null) { continue; } if (!keyIdBlock.BlockData.IsEqualTo(XvcInfo.EncryptionKeyIds[keyIndex].KeyId)) { continue; } var decryptKeyBlock = block.GetBlockWithId(XvcLicenseBlockId.EncryptedCik); if (decryptKeyBlock == null) { continue; } keyOutput = decryptKeyBlock.BlockData; // todo: decrypt/deobfuscate the key return(file); } return(null); }