The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PasteHelper.cs 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Web;
  6. using Teknik.Configuration;
  7. using Teknik.Utilities;
  8. using Teknik.Models;
  9. using Teknik.Utilities.Cryptography;
  10. using Teknik.Data;
  11. using System.IO;
  12. namespace Teknik.Areas.Paste
  13. {
  14. public static class PasteHelper
  15. {
  16. public static Models.Paste CreatePaste(Config config, TeknikEntities db, string content, string title = "", string syntax = "text", ExpirationUnit expireUnit = ExpirationUnit.Never, int expireLength = 1, string password = "")
  17. {
  18. Models.Paste paste = new Models.Paste();
  19. paste.DatePosted = DateTime.Now;
  20. paste.MaxViews = 0;
  21. paste.Views = 0;
  22. // Generate random url
  23. string url = StringHelper.RandomString(config.PasteConfig.UrlLength);
  24. while (db.Pastes.Where(p => p.Url == url).FirstOrDefault() != null)
  25. {
  26. url = StringHelper.RandomString(config.PasteConfig.UrlLength);
  27. }
  28. paste.Url = url;
  29. // Figure out the expire date (null if 'never' or 'visit')
  30. switch (expireUnit)
  31. {
  32. case ExpirationUnit.Never:
  33. break;
  34. case ExpirationUnit.Views:
  35. paste.MaxViews = expireLength;
  36. break;
  37. case ExpirationUnit.Minutes:
  38. paste.ExpireDate = paste.DatePosted.AddMinutes(expireLength);
  39. break;
  40. case ExpirationUnit.Hours:
  41. paste.ExpireDate = paste.DatePosted.AddHours(expireLength);
  42. break;
  43. case ExpirationUnit.Days:
  44. paste.ExpireDate = paste.DatePosted.AddDays(expireLength);
  45. break;
  46. case ExpirationUnit.Months:
  47. paste.ExpireDate = paste.DatePosted.AddMonths(expireLength);
  48. break;
  49. case ExpirationUnit.Years:
  50. paste.ExpireDate = paste.DatePosted.AddYears(expireLength);
  51. break;
  52. default:
  53. break;
  54. }
  55. if (!Directory.Exists(config.PasteConfig.PasteDirectory))
  56. {
  57. Directory.CreateDirectory(config.PasteConfig.PasteDirectory);
  58. }
  59. // Generate a unique file name that does not currently exist
  60. string filePath = FileHelper.GenerateRandomFileName(config.PasteConfig.PasteDirectory, config.PasteConfig.FileExtension, 10);
  61. string fileName = Path.GetFileName(filePath);
  62. string key = GenerateKey(config.PasteConfig.KeySize);
  63. string iv = GenerateIV(config.PasteConfig.BlockSize);
  64. if (!string.IsNullOrEmpty(password))
  65. {
  66. paste.HashedPassword = HashPassword(key, password);
  67. }
  68. // Encrypt the contents to the file
  69. EncryptContents(content, filePath, password, key, iv, config.PasteConfig.KeySize, config.PasteConfig.ChunkSize);
  70. // Generate a deletion key
  71. string delKey = StringHelper.RandomString(config.PasteConfig.DeleteKeyLength);
  72. paste.Key = key;
  73. paste.KeySize = config.PasteConfig.KeySize;
  74. paste.IV = iv;
  75. paste.BlockSize = config.PasteConfig.BlockSize;
  76. paste.FileName = fileName;
  77. //paste.Content = content;
  78. paste.Title = title;
  79. paste.Syntax = syntax;
  80. paste.DeleteKey = delKey;
  81. return paste;
  82. }
  83. public static bool CheckExpiration(Models.Paste paste)
  84. {
  85. if (paste.ExpireDate != null && DateTime.Now >= paste.ExpireDate)
  86. return true;
  87. if (paste.MaxViews > 0 && paste.Views > paste.MaxViews)
  88. return true;
  89. return false;
  90. }
  91. public static string GenerateKey(int keySize)
  92. {
  93. return StringHelper.RandomString(keySize / 8);
  94. }
  95. public static string GenerateIV(int ivSize)
  96. {
  97. return StringHelper.RandomString(ivSize / 16);
  98. }
  99. public static string HashPassword(string key, string password)
  100. {
  101. return SHA384.Hash(key, password).ToHex();
  102. }
  103. public static void EncryptContents(string content, string filePath, string password, string key, string iv, int keySize, int chunkSize)
  104. {
  105. byte[] ivBytes = Encoding.Unicode.GetBytes(iv);
  106. byte[] keyBytes = AesCounterManaged.CreateKey(key, ivBytes, keySize);
  107. // Set the hashed password if one is provided and modify the key
  108. if (!string.IsNullOrEmpty(password))
  109. {
  110. keyBytes = AesCounterManaged.CreateKey(password, ivBytes, keySize);
  111. }
  112. // Encrypt Content
  113. byte[] data = Encoding.Unicode.GetBytes(content);
  114. using (MemoryStream ms = new MemoryStream(data))
  115. {
  116. AesCounterManaged.EncryptToFile(filePath, ms, chunkSize, keyBytes, ivBytes);
  117. }
  118. }
  119. }
  120. }