private byte[] FetchId(FPProvider provider, SPCMessage spc, CKCMessage ckc) { IEnumerable <TLLVSlab> spcSlabs = null; try { spcSlabs = TLLVSlab.FromBuffer(spc.UnscrambledPayload(provider.RSAKey)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2030", "Unable to process inspection. See 'innerException' for more information.", ex); } AssetPayload AssetPayload = null; try { AssetPayload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.Asset)).Payload <AssetPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2031", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] ID = null; try { ID = AssetPayload.Identifier; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2032", "Unable to process inspection. See 'innerException' for more information.", ex); } return(ID); }
private async Task <CKCMessage> GenerateCKC(FPProvider provider, SPCMessage spc, object info) { if (spc == null) { throw new FPInvalidContextException("EXC_0004", "Null SPCMessage received. Unable to process request."); } if (provider == null) { throw new FPInvalidProviderException("EXC_0005", "Null FPProvider received. Unable to process request."); } if (Enumerable.SequenceEqual(provider.Hash, spc.ProviderHash) == false) { throw new FPInvalidProviderException("EXC_0006", "Received SPCMessage contains a unregistered FairPlay provider."); } IEnumerable <TLLVSlab> spcSlabs = null; try { spcSlabs = TLLVSlab.FromBuffer(spc.UnscrambledPayload(provider.RSAKey)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0007", "Unable to process SPC. See 'innerException' for more information.", ex); } IEnumerable <TLLVSlab> ckcSlabs = null; try { ckcSlabs = await GenerateCKC(new DFunction(provider.ASKey), spcSlabs, info); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0008", "Unable to process CKC. See 'innerException' for more information.", ex); } byte[] seed = null; try { seed = spcSlabs.First(s => s.Tag.Same(TLLVTag.Id.AR)).Payload <ARPayload>().Seed; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0009", "Unable to process SPC. See 'innerException' for more information.", ex); } byte[] random = null; try { random = ckcSlabs.First(s => s.Tag.Same(TLLVTag.Id.R1)).Payload <R1Payload>().R1; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0010", "Unable to process SPC. See 'innerException' for more information.", ex); } byte[] key = null; try { using (var sha = SHA1.Create()) using (var aes = Aes.Create()) { // aes.IV = new byte[16]; aes.Key = sha.ComputeHash(random).Take(16).ToArray(); aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; using (var encryptor = aes.CreateEncryptor()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(seed); key = memoryStream.ToArray(); } } } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0011", "Unable to process CKC. See 'innerException' for more information.", ex); } byte[] iv = new byte[16]; try { new Random().NextBytes(iv); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0012", "Unable to process CKC. See 'innerException' for more information.", ex); } byte[] ckc = null; try { ckc = TLLVCrypto.ScrambledPayload(TLLVSlab.ToBuffer(ckcSlabs), iv, key); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_0013", "Unable to process CKC. See 'innerException' for more information.", ex); } return(new CKCMessage(1, iv, ckc)); }
private IContentKey FetchKey(FPProvider provider, SPCMessage spc, CKCMessage ckc) { IEnumerable <TLLVSlab> spcSlabs = null; try { spcSlabs = TLLVSlab.FromBuffer(spc.UnscrambledPayload(provider.RSAKey)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2010", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] DASk = null; try { DASk = new DFunction(provider.ASKey).DeriveBytes(spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.R2)).Payload <R2Payload>().R2); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2011", "Unable to process inspection. See 'innerException' for more information.", ex); } SKR1Payload SessionRandom1Payload = null; try { SessionRandom1Payload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.SKR1)).Payload <SKR1Payload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2012", "Unable to process inspection. See 'innerException' for more information.", ex); } SKR1IntegrityPayload SessionRandom1IntegrityPayload = null; try { SessionRandom1IntegrityPayload = spcSlabs.First(p => p.Tag.Same(TLLVTag.Id.SKR1Integrity)).Payload <SKR1IntegrityPayload>(); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2013", "Unable to process inspection. See 'innerException' for more information.", ex); } SKR1Parcel SessionRandom1Parcel = null; try { SessionRandom1Parcel = new SKR1Parcel(new ReadOnlyMemory <byte>(SessionRandom1Payload.UnscrambledParcel(DASk))); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2014", "Unable to process inspection. See 'innerException' for more information.", ex); } if (Enumerable.SequenceEqual(SessionRandom1Parcel.Integrity, SessionRandom1IntegrityPayload.Integrity) == false) { throw new FPContextIntegrityViolatedException("EXC_0034", "Unable to process SPC. SPC integrity violated."); } byte[] seed = null; try { seed = spcSlabs.First(s => s.Tag.Same(TLLVTag.Id.AR)).Payload <ARPayload>().Seed; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2015", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] random = null; try { random = SessionRandom1Parcel.R1; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2016", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] key = null; try { using (var sha = SHA1.Create()) using (var aes = Aes.Create()) { // aes.IV = new byte[16]; aes.Key = sha.ComputeHash(random).Take(16).ToArray(); aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; using (var encryptor = aes.CreateEncryptor()) using (var memoryStream = new MemoryStream()) using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(seed); key = memoryStream.ToArray(); } } } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2017", "Unable to process inspection. See 'innerException' for more information.", ex); } IEnumerable <TLLVSlab> ckcSlabs = null; try { ckcSlabs = TLLVSlab.FromBuffer(ckc.UnscrambledPayload(key)); } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2018", "Unable to process inspection. See 'innerException' for more information.", ex); } byte[] SK = null; try { SK = SessionRandom1Parcel.SK; } catch (FPException) { throw; } catch (Exception ex) { throw new FPInvalidContextException("EXC_2019", "Unable to process inspection. See 'innerException' for more information.", ex); } return(FetchKey(spcSlabs, ckcSlabs, SK)); }