EaseFilter Demo Project
DigitalRightControl.cs
Go to the documentation of this file.
1 //
3 // (C) Copyright 2011 EaseFilter Technologies Inc.
4 // All Rights Reserved
5 //
6 // This software is part of a licensed software product and may
7 // only be used or copied in accordance with the terms of that license.
8 //
10 
11 using System;
12 using System.Text;
13 using System.IO;
14 using System.Collections;
15 using System.Collections.Generic;
16 using Microsoft.Win32.SafeHandles;
17 using System.Runtime.InteropServices;
18 using System.Security.Principal;
19 using System.Security.Cryptography;
20 using System.Xml.Serialization;
21 
22 namespace EaseFilter.CommonObjects
23 {
24  public enum AESFlags : uint
25  {
26  Flags_Enabled_Expire_Time = 0x00000010,
28  Flags_Enabled_Check_UserName = 0x00000040,
31  Flags_AES_Key_Was_Embedded = 0x00000200,
36 
37  }
38 
42  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
43  public class DRPolicy
44  {
48  public string IncludeProcessNames;
52  public string ExcludeProcessNames;
56  public string IncludeUserNames;
60  public string ExcludeUserNames;
64  public string IncludeComputerIds;
68  public string UserPassword;
72  public string AccessFlags;
76  public long ExpireTime;
80  public long CreationTime;
84  public string FileName;
85  }
86 
92  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
93  public struct DRPolicyData
94  {
95  public uint AESVerificationKey;
97  public uint IVLength;
98  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
99  public byte[] IV;
100  public uint EncryptionKeyLength;
101  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
102  public byte[] EncryptionKey;
103  public long CreationTime;
104  public long ExpireTime;
105  public uint AccessFlags;
106  public long FileSize;
115  public uint LengthOfAccountName;
116  public uint OffsetOfAccountName;
117  public uint LengthOfComputerIds;
118  public uint OffsetOfComputerIds;
119  public uint LengthOfUserPassword;
120  public uint OffsetOfUserPassword;
121  public string IncludeProcessNames;
122  public string ExcludeProcessNames;
123  public string IncludeUserNames;
124  public string ExcludeUserNames;
125  public string AccountName;
126  public string ComputerIds;
127  public string UserPassword;
128  public uint SizeOfAESData;
129 
130  }
131 
132 
133  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
134  public struct UserInfo
135  {
139  public string AccountName;
143  public string AccountPassword;
147  public string ProcessName;
151  public string UserName;
155  public string ComputerId;
159  public string FileName;
163  public long CreationTime;
167  public string UserPassword;
168  }
169 
170 
171  public class DigitalRightControl
172  {
173  public static string SECURE_SHARE_FILE_EXTENSION = ".psf";
174  public const uint AES_VERIFICATION_KEY = 0xccb76e80;
175  public static string WorkingFolder = string.Empty;
176  public static string PassPhrase = string.Empty;
177 
178  private static byte[] GetPolicyBuffer(long fileSize,DRPolicyData policy,byte[] iv, byte[] encryptionKey)
179  {
180  MemoryStream ms = new MemoryStream();
181  BinaryWriter bw = new BinaryWriter(ms);
182  bw.Write(AES_VERIFICATION_KEY);
183  bw.Write((uint)(policy.AESFlags));
184  bw.Write(iv.Length);
185  bw.Write(iv);
186  bw.Write(encryptionKey.Length);
187 
188  if (encryptionKey.Length < 32)
189  {
190  //the struture always keep 32 bytes for encryption key.
191  Array.Resize(ref encryptionKey, 32);
192  }
193 
194  bw.Write(encryptionKey);
195  bw.Write(policy.CreationTime);
196  bw.Write(policy.ExpireTime);
197  bw.Write((uint)policy.AccessFlags);
198  bw.Write(fileSize);
199  bw.Write(policy.LengthOfIncludeProcessNames);
200 
201  //the first offset lenght = current position + 13*4
202  // sizeof(OffsetOfIncludeProcessNames) + sizeof(OffsetOfExcludeProcessNames) + sizeof(LengthOfExcludeProcessNames)
203  // + sizeof(OffsetOfIncludeUserNames) + sizeof(LengthOfIncludeUserNames) + sizeof(OffsetOfExcludeUserNames) + sizeof(LengthOfExcludeUserNames)
204  // + sizeof(OffsetOfAccountName) + sizeof(LengthOfAccountName) + sizeof(OffsetOfComputerIds) + sizeof(LengthOfComputerIds)
205  // + sizeof(LengthOfUserPassword) + sizeof(OffsetOfUserPassword)
206 
207  policy.OffsetOfIncludeProcessNames = (uint)ms.Length + 13 * 4;
208  bw.Write(policy.OffsetOfIncludeProcessNames);
209 
210  bw.Write(policy.LengthOfExcludeProcessNames);
212  bw.Write(policy.OffsetOfExcludeProcessNames);
213 
214  bw.Write(policy.LengthOfIncludeUserNames);
216  bw.Write(policy.OffsetOfIncludeUserNames);
217 
218  bw.Write(policy.LengthOfExcludeUserNames);
220  bw.Write(policy.OffsetOfExcludeUserNames);
221 
222  bw.Write(policy.LengthOfAccountName);
224  bw.Write(policy.OffsetOfAccountName);
225 
226  bw.Write(policy.LengthOfComputerIds);
228  bw.Write(policy.OffsetOfComputerIds);
229 
230  bw.Write(policy.LengthOfUserPassword);
232  bw.Write(policy.OffsetOfUserPassword);
233 
234 
235  byte[] strBuffer;
236  if (policy.LengthOfIncludeProcessNames > 0)
237  {
238  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeProcessNames);
239  bw.Write(strBuffer);
240  }
241 
242  if (policy.LengthOfExcludeProcessNames > 0)
243  {
244  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeProcessNames);
245  bw.Write(strBuffer);
246  }
247 
248  if (policy.LengthOfIncludeUserNames > 0)
249  {
250  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.IncludeUserNames);
251  bw.Write(strBuffer);
252  }
253 
254  if (policy.LengthOfExcludeUserNames > 0)
255  {
256  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ExcludeUserNames);
257  bw.Write(strBuffer);
258  }
259 
260  if (policy.LengthOfAccountName > 0)
261  {
262  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.AccountName);
263  bw.Write(strBuffer);
264  }
265 
266  if (policy.LengthOfComputerIds > 0)
267  {
268 
269  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.ComputerIds);
270  bw.Write(strBuffer);
271  }
272 
273  if (policy.LengthOfUserPassword > 0)
274  {
275  strBuffer = UnicodeEncoding.Unicode.GetBytes(policy.UserPassword);
276  bw.Write(strBuffer);
277  }
278 
279  byte[] AESBuffer = ms.ToArray();
280 
281  //encrypt the access policy except the sizeOfAESData;
282  FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, null, null);
283 
284  return AESBuffer;
285  }
286 
296  public static bool EncryptFileWithEmbeddedDRPolicy(string sourceFileName, string destFileName, byte[] encryptIV, byte[] encryptKey,DRPolicyData policy, out string lastError)
297  {
298  bool ret = false;
299  FileStream fs = null;
300  lastError = string.Empty;
301 
302  try
303  {
304  if (!File.Exists(sourceFileName))
305  {
306  lastError = sourceFileName + " doesn't exist.";
307  return false;
308  }
309 
310  FileInfo fileInfo = new FileInfo(sourceFileName);
311  long fileSize = fileInfo.Length;
312 
313  byte[] AESBuffer = GetPolicyBuffer(fileSize, policy, encryptIV, encryptKey);
314 
315 
316  //encrypt the file with encryption key and a iv key.
317  ret = FilterAPI.AESEncryptFileToFile(sourceFileName, destFileName, (uint)encryptKey.Length, encryptKey, (uint)encryptIV.Length, encryptIV, false);
318  if (!ret)
319  {
320  lastError = "Create encrypt file " + destFileName + " failed with error:" + FilterAPI.GetLastErrorMessage();
321  return ret;
322  }
323 
324  fs = new FileStream(destFileName, FileMode.Append, FileAccess.Write, FileShare.Read);
325 
326  //append the DR policy to the encrypted file.
327  fs.Write(AESBuffer, 0, AESBuffer.Length);
328 
329  //append the sizeof the DR policy
330  fs.Write(BitConverter.GetBytes(AESBuffer.Length + 4 ), 0, 4);
331 
332  }
333  catch (Exception ex)
334  {
335  ret = false;
336  lastError = "Encrypt file " + sourceFileName + " failed with error:" + ex.Message;
337  }
338  finally
339  {
340  if (null != fs)
341  {
342  fs.Close();
343  }
344  }
345 
346  return ret;
347  }
348 
357  public static bool ProcessSecureShareFile(string fileName, out string lastError)
358  {
359  bool ret = false;
360  lastError = string.Empty;
361 
362  try
363  {
364  if (!File.Exists(fileName))
365  {
366  lastError = fileName + " doesn't exist.";
367  return false;
368  }
369 
370  if (!fileName.EndsWith(SECURE_SHARE_FILE_EXTENSION))
371  {
372  lastError = fileName + " extension is not correct.";
373  return false;
374  }
375 
376  FileAttributes attributes = File.GetAttributes(fileName);
377  attributes = (~FileAttributes.ReadOnly) & attributes;
378  File.SetAttributes(fileName, attributes);
379 
380  FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
381  long fileSize = fs.Length;
382 
383  //read the last 4 bytes data, it is the total size of the embedded data.
384 
385  fs.Position = fileSize - 4;
386  BinaryReader br = new BinaryReader(fs);
387  uint sizeOfAESData = br.ReadUInt32();
388 
389  if (sizeOfAESData >= fileSize)
390  {
391  lastError = fileName + " is not valid share encrypted file, the sizeOfAESData:" + sizeOfAESData + " >= file size:" + fileSize;
392  return false;
393  }
394 
395  fs.Position = fileSize - sizeOfAESData;
396 
397  //Read the embedded data
398  byte[] AESBuffer = new byte[sizeOfAESData];
399  fs.Read(AESBuffer, 0, (int)sizeOfAESData);
400 
401  //decrypt the embedded data, since the last 4 bytes is not encrypted, after decryption,need to write the clear size back.
402  FilterAPI.AESEncryptDecryptBuffer(AESBuffer, 0, null, null);
403 
404  //since the last 4 bytes for sizeOfAESData is not encrypted, we need to put back the clear value back.
405  MemoryStream ms = new MemoryStream(AESBuffer);
406  ms.Position = 0;
407  br = new BinaryReader(ms);
408  uint verificationKey = br.ReadUInt32();
409 
410  //verify if this is the valid embedded data.
411  if (verificationKey != AES_VERIFICATION_KEY)
412  {
413  lastError = fileName + " is not valid share encrypted file, the encryption key:" + verificationKey + " is not valid.";
414  return false;
415  }
416 
417  //write back the size of embedded data here.
418  ms.Position = ms.Length - 4;
419  BinaryWriter bw = new BinaryWriter(ms);
420  bw.Write(sizeOfAESData);
421 
422  //Remove the embedded data, this is the original file size without the embedded information.
423  fs.SetLength(fileSize - sizeOfAESData);
424 
425  fs.Close();
426  fs = null;
427 
428  string newFileName = fileName.Remove(fileName.Length - SECURE_SHARE_FILE_EXTENSION.Length);
429 
430  File.Move(fileName, newFileName);
431  //add the DR data to the encrypted file as a tag data.
432  ret = FilterAPI.EmbedDRPolicyDataToFile(newFileName, AESBuffer, out lastError);
433 
434  }
435  catch (Exception ex)
436  {
437  ret = false;
438  lastError = "ProcessSecureShareFile " + fileName + " failed with error:" + ex.Message;
439  }
440 
441 
442  return ret;
443  }
444 
445 
446  public static T DecryptStrToObject<T>( string toDeserialize)
447  {
448  string decryptedStr = FilterAPI.AESEncryptDecryptStr(toDeserialize, FilterAPI.EncryptType.Decryption);
449 
450  XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
451  StringReader textReader = new StringReader(decryptedStr);
452  return (T)xmlSerializer.Deserialize(textReader);
453  }
454 
455  public static string EncryptObjectToStr<T>( T toSerialize)
456  {
457  XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
458  StringWriter textWriter = new StringWriter();
459  xmlSerializer.Serialize(textWriter, toSerialize);
460 
461  string encryptedText = FilterAPI.AESEncryptDecryptStr(textWriter.ToString(), FilterAPI.EncryptType.Encryption);
462 
463  return encryptedText;
464  }
465 
466 
467  }
468 }
static bool ProcessSecureShareFile(string fileName, out string lastError)
Process the encrypted file&#39;s embedded access policy, remove embedded information, add AESTagData to e...
enum _AESFlags AESFlags
string ExcludeUserNames
If it is not empty, all the useres in the user name list can not access the files.
string UserName
the user name who access the file.
string FileName
the encrypted file which was accessed.
ULONG PUCHAR encryptionKey
Definition: FilterAPI.h:561
string UserPassword
the password of the user input.
LPCTSTR destFileName
Definition: FilterAPI.h:757
long ExpireTime
The file will be expired after the expire time, and it can&#39;t be accessed.
string AccessFlags
the access flags of the shared file.
string ComputerId
the computer information which access the file.
string IncludeUserNames
If it is not empty, only the users in the user name list can access the files.
string IncludeProcessNames
If it is not empty, only the processes in the process list can access the files.
string AccountName
the owner account name
string FileName
the file name which was applied with policy.
This is the DR info meta data which will be stored in server if revoke access control is enabled...
unsigned char iv[]
long CreationTime
The time of the encrypted file was created.
long CreationTime
the creation time of the file which was accessed.
LONGLONG fileSize
Definition: FilterAPI.h:684
This the DR data which will be embedded to the encyrpted file if the revoke access control flag is no...
string ExcludeProcessNames
If it is not empty, all the processes in the process list can not access the files.
string AccountPassword
the password of the account
string ProcessName
the process name which access the file.
static bool EncryptFileWithEmbeddedDRPolicy(string sourceFileName, string destFileName, byte[] encryptIV, byte[] encryptKey, DRPolicyData policy, out string lastError)
Create an encrypted file with embedded digital right policy, distribute the encrypted file via intern...
string UserPassword
the password of the shared file.
string IncludeComputerIds
If it is not empty, only the computer in the computer id list can access the files.

Social Network


Services Overview

Architect, implement and test file system filter drivers for a wide range of functionality. We can offer several levels of assistance to meet your specific.

Contact Us

You are welcome to contact us for salse or partnership.

Sales: sales@easefilter.com
Support: support@easefilter.com
Info: info@easefilter.com