94 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Org.BouncyCastle.Crypto;
 | |
| using Org.BouncyCastle.Crypto.Digests;
 | |
| using Org.BouncyCastle.Crypto.Encodings;
 | |
| using Org.BouncyCastle.Crypto.Engines;
 | |
| using Org.BouncyCastle.Crypto.Signers;
 | |
| using Org.BouncyCastle.OpenSsl;
 | |
| using ProtoBuf;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.IO;
 | |
| using System.Text;
 | |
| 
 | |
| namespace WidevineClient.Widevine
 | |
| {
 | |
|     public class CDMDevice
 | |
|     {
 | |
|         public string DeviceName { get; set; }
 | |
|         public ClientIdentification ClientID { get; set; }
 | |
|         AsymmetricCipherKeyPair DeviceKeys { get; set; }
 | |
| 
 | |
|         public virtual bool IsAndroid { get; set; } = true;
 | |
| 
 | |
|         public CDMDevice(string deviceName, byte[] clientIdBlobBytes = null, byte[] privateKeyBytes = null, byte[] vmpBytes = null)
 | |
|         {
 | |
|             DeviceName = deviceName;
 | |
| 
 | |
|             string privateKeyPath = Path.Join(Constants.DEVICES_FOLDER, deviceName, "device_private_key");
 | |
|             string vmpPath = Path.Join(Constants.DEVICES_FOLDER, deviceName, "device_vmp_blob");
 | |
| 
 | |
|             if (clientIdBlobBytes == null)
 | |
|             {
 | |
|                 string clientIDPath = Path.Join(Constants.DEVICES_FOLDER, deviceName, "device_client_id_blob");
 | |
| 
 | |
|                 if (!File.Exists(clientIDPath))
 | |
|                     throw new Exception("No client id blob found");
 | |
| 
 | |
|                 clientIdBlobBytes = File.ReadAllBytes(clientIDPath);
 | |
|             }
 | |
| 
 | |
|             ClientID = Serializer.Deserialize<ClientIdentification>(new MemoryStream(clientIdBlobBytes));
 | |
| 
 | |
|             if (privateKeyBytes != null)
 | |
|             {
 | |
|                 using var reader = new StringReader(Encoding.UTF8.GetString(privateKeyBytes));
 | |
|                 DeviceKeys = (AsymmetricCipherKeyPair)new PemReader(reader).ReadObject();
 | |
|             }
 | |
|             else if (File.Exists(privateKeyPath))
 | |
|             {
 | |
|                 using var reader = File.OpenText(privateKeyPath);
 | |
|                 DeviceKeys = (AsymmetricCipherKeyPair)new PemReader(reader).ReadObject();
 | |
|             }
 | |
| 
 | |
|             if (vmpBytes != null)
 | |
|             {
 | |
|                 var vmp = Serializer.Deserialize<FileHashes>(new MemoryStream(vmpBytes));
 | |
|                 ClientID.FileHashes = vmp;
 | |
|             }
 | |
|             else if (File.Exists(vmpPath))
 | |
|             {
 | |
|                 var vmp = Serializer.Deserialize<FileHashes>(new MemoryStream(File.ReadAllBytes(vmpPath)));
 | |
|                 ClientID.FileHashes = vmp;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public virtual byte[] Decrypt(byte[] data)
 | |
|         {
 | |
|             OaepEncoding eng = new OaepEncoding(new RsaEngine());
 | |
|             eng.Init(false, DeviceKeys.Private);
 | |
| 
 | |
|             int length = data.Length;
 | |
|             int blockSize = eng.GetInputBlockSize();
 | |
| 
 | |
|             List<byte> plainText = new List<byte>();
 | |
| 
 | |
|             for (int chunkPosition = 0; chunkPosition < length; chunkPosition += blockSize)
 | |
|             {
 | |
|                 int chunkSize = Math.Min(blockSize, length - chunkPosition);
 | |
|                 plainText.AddRange(eng.ProcessBlock(data, chunkPosition, chunkSize));
 | |
|             }
 | |
| 
 | |
|             return plainText.ToArray();
 | |
|         }
 | |
| 
 | |
|         public virtual byte[] Sign(byte[] data)
 | |
|         {
 | |
|             PssSigner eng = new PssSigner(new RsaEngine(), new Sha1Digest());
 | |
| 
 | |
|             eng.Init(true, DeviceKeys.Private);
 | |
|             eng.BlockUpdate(data, 0, data.Length);
 | |
|             return eng.GenerateSignature();
 | |
|         }
 | |
|     }
 | |
| }
 |