示例#1
0
        public async Task <byte[]> GenerateCKC(byte[]  spc, object info = null)
        {
            var buffer = new ReadOnlyMemory <byte>(spc);

            // We try to read SPC message.
            SPCMessage request = null;

            try { request = new SPCMessage(buffer); }
            catch (FPException) {  throw; }
            catch (Exception ex) { throw new FPInvalidContextException("EXC_0001", "Unable to parse SPC. See 'innerException' for more information.", ex); }

            FPProvider provider = null;

            try { provider = this.Providers.First(p => Enumerable.SequenceEqual(p.Hash, request.ProviderHash)); }
            catch (FPException) {  throw; }
            catch (Exception ex) { throw new FPInvalidProviderException("EXC_0002", "Received SPCMessage contains a unregistered FairPlay provider.", ex); }

            CKCMessage response = null;

            try { response = await GenerateCKC(provider, request, info); }
            catch (FPException) {  throw; }
            catch (Exception ex) { throw new FPInvalidContextException("EXC_0003", "Unable to process SPC. See 'innerException' for more information.", ex); }

            return(response.Binary);
        }
示例#2
0
        public IContentKey FetchKey(byte[]  spc, byte[] ckc)
        {
            var spcBuffer = new ReadOnlyMemory <byte>(spc);
            var ckcBuffer = new ReadOnlyMemory <byte>(ckc);

            // We try to read SPC message.
            SPCMessage request = null;

            try { request = new SPCMessage(spcBuffer); }
            catch (FPException) {  throw; }
            catch (Exception ex) { throw new FPInvalidContextException("EXC_2001", "Unable to parse SPC. See 'innerException' for more information.", ex); }

            CKCMessage response = null;

            try { response = new CKCMessage(ckcBuffer); }
            catch (FPException) {  throw; }
            catch (Exception ex) { throw new FPInvalidContextException("EXC_2002", "Unable to parse CKC. See 'innerException' for more information.", ex); }

            FPProvider provider = null;

            try { provider = this.Providers.First(p => Enumerable.SequenceEqual(p.Hash, request.ProviderHash)); }
            catch (FPException) {  throw; }
            catch (Exception ex) { throw new FPInvalidProviderException("EXC_2003", "Received SPCMessage contains a unregistered FairPlay provider.", ex); }

            return(FetchKey(provider, request, response));
        }
示例#3
0
        public FPExtractor(FPProvider provider)
        {
            ArgumentThrow.IfNull(provider, "Unable to create inspector. Provider can not be null.", nameof(provider));

            this.Providers = new List <FPProvider>()
            {
                provider
            };
        }
示例#4
0
        public FPServer(FPProvider provider, IContentKeyLocator locator)
        {
            ArgumentThrow.IfNull(provider, "Unable to create server. Provider can not be null.", nameof(provider));
            ArgumentThrow.IfNull(locator, "Unable to create server. Key locator can not be null.", nameof(locator));

            this.Providers = new List <FPProvider>()
            {
                provider
            };
            this.Locator = locator;

            this.LicenseDuration = 3600;
        }
示例#5
0
        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);
        }
示例#6
0
        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));
        }
示例#7
0
        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));
        }