├── .gitattributes ├── .gitignore ├── DecryptESD.sln ├── DecryptESD.sln.DotSettings ├── DecryptESD ├── DecryptESD.csproj └── Program.cs ├── LICENSE.md ├── Legacy └── DecryptESD │ ├── App.config │ ├── CliOptions.cs │ ├── CryptoKey.cs │ ├── CryptoKeys.xml │ ├── DecryptESD.csproj │ ├── Exceptions.cs │ ├── IO │ ├── IntegrityTable.cs │ ├── IntegrityTableHeader.cs │ ├── ResourceHeader.cs │ ├── ResourceHeaderFlags.cs │ ├── WimFile.cs │ ├── WimHeader.cs │ └── WimHeaderFlags.cs │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ └── Settings.settings │ └── packages.config ├── README.md ├── WIMCore.Tests ├── IntegrityTests.cs ├── LoadTests.cs ├── TestFiles │ ├── Error-InvalidMagic.wim │ ├── Error-InvalidSize.wim │ ├── Win10-RS1-BrokenIntegrity.wim │ ├── Win10-RS1-CompressFast.wim │ ├── Win10-RS1-CompressMax.wim │ ├── Win10-RS1-CompressNone.wim │ ├── Win10-RS1-Integrity.wim │ └── Win10-RS1-MultiImage-Integrity.wim └── WIMCore.Tests.csproj ├── WIMCore ├── Compression │ ├── LzmsStream.cs │ ├── LzxStream.cs │ └── XpressStream.cs ├── DirectoryEntry.cs ├── DirectoryTableEntry.cs ├── Exceptions │ ├── WimIntegrityException.cs │ ├── WimIntegrityExceptionType.cs │ ├── WimInvalidException.cs │ └── WimInvalidExceptionType.cs ├── IntegrityTable.cs ├── IntegrityTableHeader.cs ├── LookupEntry.cs ├── LookupTable.cs ├── ResourceHeader.cs ├── ResourceHeaderFlags.cs ├── SecurityTable.cs ├── SecurityTableHeader.cs ├── StreamEntry.cs ├── WIMCore.csproj ├── WimFile.cs ├── WimHeader.cs ├── WimHeaderFlags.cs └── WimImage.cs └── Website └── CryptoKeySite ├── App_Start ├── FilterConfig.cs ├── MongoConfig.cs └── RouteConfig.cs ├── Controllers └── WebController.cs ├── CryptoKeySite.csproj ├── Global.asax ├── Global.asax.cs ├── Models ├── CryptoKey.cs ├── IModelWithId.cs ├── LoginViewModel.cs ├── MongoRepository.cs └── RegisterViewModel.cs ├── Properties └── AssemblyInfo.cs ├── Views ├── Shared │ ├── Error.cshtml │ └── _Layout.cshtml ├── Web │ ├── Add.cshtml │ ├── Index.cshtml │ ├── Login.cshtml │ └── Register.cshtml ├── _ViewStart.cshtml └── web.config ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── bundleconfig.json ├── compilerconfig.json ├── compilerconfig.json.defaults ├── gulpfile.js ├── package.json ├── packages.config └── res ├── scss ├── default.css ├── default.min.css └── default.scss └── ts ├── default.js ├── default.js.map ├── default.min.js └── default.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ 246 | *.snk 247 | 248 | # Excluded folders 249 | PublishProfiles/ -------------------------------------------------------------------------------- /DecryptESD.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26206.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documents", "Documents", "{DE8252A8-7832-4FFA-A09D-60C4AF3D3D76}" 7 | ProjectSection(SolutionItems) = preProject 8 | LICENSE.md = LICENSE.md 9 | README.md = README.md 10 | EndProjectSection 11 | EndProject 12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Legacy", "Legacy", "{87C864DB-5E75-4E57-8D5A-5466B57CB6A4}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Website", "Website", "{D96C41F7-2D2A-4D21-9F6D-AEAA3F984887}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DecryptESD", "Legacy\DecryptESD\DecryptESD.csproj", "{C2500A05-8C18-47E8-B780-8C40CA471D20}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CryptoKeySite", "Website\CryptoKeySite\CryptoKeySite.csproj", "{B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DecryptESD", "DecryptESD\DecryptESD.csproj", "{1272382C-E1E3-4FD7-96F8-01542A469F8C}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WIMCore.Tests", "WIMCore.Tests\WIMCore.Tests.csproj", "{08930279-5879-43B9-9596-4EB599902B79}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WIMCore", "WIMCore\WIMCore.csproj", "{DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}" 25 | EndProject 26 | Global 27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 28 | Debug|Any CPU = Debug|Any CPU 29 | Debug|x64 = Debug|x64 30 | Debug|x86 = Debug|x86 31 | Release|Any CPU = Release|Any CPU 32 | Release|x64 = Release|x64 33 | Release|x86 = Release|x86 34 | EndGlobalSection 35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 36 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Debug|x64.ActiveCfg = Debug|Any CPU 39 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Debug|x64.Build.0 = Debug|Any CPU 40 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Debug|x86.ActiveCfg = Debug|Any CPU 41 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Debug|x86.Build.0 = Debug|Any CPU 42 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Release|x64.ActiveCfg = Release|Any CPU 45 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Release|x64.Build.0 = Release|Any CPU 46 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Release|x86.ActiveCfg = Release|Any CPU 47 | {C2500A05-8C18-47E8-B780-8C40CA471D20}.Release|x86.Build.0 = Release|Any CPU 48 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Debug|x64.ActiveCfg = Debug|Any CPU 51 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Debug|x64.Build.0 = Debug|Any CPU 52 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Debug|x86.ActiveCfg = Debug|Any CPU 53 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Debug|x86.Build.0 = Debug|Any CPU 54 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Release|x64.ActiveCfg = Release|Any CPU 57 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Release|x64.Build.0 = Release|Any CPU 58 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Release|x86.ActiveCfg = Release|Any CPU 59 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B}.Release|x86.Build.0 = Release|Any CPU 60 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Debug|x64.ActiveCfg = Debug|x64 63 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Debug|x64.Build.0 = Debug|x64 64 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Debug|x86.ActiveCfg = Debug|x86 65 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Debug|x86.Build.0 = Debug|x86 66 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Release|x64.ActiveCfg = Release|x64 69 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Release|x64.Build.0 = Release|x64 70 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Release|x86.ActiveCfg = Release|x86 71 | {1272382C-E1E3-4FD7-96F8-01542A469F8C}.Release|x86.Build.0 = Release|x86 72 | {08930279-5879-43B9-9596-4EB599902B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {08930279-5879-43B9-9596-4EB599902B79}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {08930279-5879-43B9-9596-4EB599902B79}.Debug|x64.ActiveCfg = Debug|x64 75 | {08930279-5879-43B9-9596-4EB599902B79}.Debug|x64.Build.0 = Debug|x64 76 | {08930279-5879-43B9-9596-4EB599902B79}.Debug|x86.ActiveCfg = Debug|x86 77 | {08930279-5879-43B9-9596-4EB599902B79}.Debug|x86.Build.0 = Debug|x86 78 | {08930279-5879-43B9-9596-4EB599902B79}.Release|Any CPU.ActiveCfg = Release|Any CPU 79 | {08930279-5879-43B9-9596-4EB599902B79}.Release|Any CPU.Build.0 = Release|Any CPU 80 | {08930279-5879-43B9-9596-4EB599902B79}.Release|x64.ActiveCfg = Release|x64 81 | {08930279-5879-43B9-9596-4EB599902B79}.Release|x64.Build.0 = Release|x64 82 | {08930279-5879-43B9-9596-4EB599902B79}.Release|x86.ActiveCfg = Release|x86 83 | {08930279-5879-43B9-9596-4EB599902B79}.Release|x86.Build.0 = Release|x86 84 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 85 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Debug|Any CPU.Build.0 = Debug|Any CPU 86 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Debug|x64.ActiveCfg = Debug|x64 87 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Debug|x64.Build.0 = Debug|x64 88 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Debug|x86.ActiveCfg = Debug|x86 89 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Debug|x86.Build.0 = Debug|x86 90 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Release|Any CPU.ActiveCfg = Release|Any CPU 91 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Release|Any CPU.Build.0 = Release|Any CPU 92 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Release|x64.ActiveCfg = Release|x64 93 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Release|x64.Build.0 = Release|x64 94 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Release|x86.ActiveCfg = Release|x86 95 | {DC2DE2A5-364A-45D7-AC1A-558E1A8E4CD2}.Release|x86.Build.0 = Release|x86 96 | EndGlobalSection 97 | GlobalSection(SolutionProperties) = preSolution 98 | HideSolutionNode = FALSE 99 | EndGlobalSection 100 | GlobalSection(NestedProjects) = preSolution 101 | {C2500A05-8C18-47E8-B780-8C40CA471D20} = {87C864DB-5E75-4E57-8D5A-5466B57CB6A4} 102 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B} = {D96C41F7-2D2A-4D21-9F6D-AEAA3F984887} 103 | EndGlobalSection 104 | EndGlobal 105 | -------------------------------------------------------------------------------- /DecryptESD.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | <?xml version="1.0" encoding="utf-16"?><Profile name="Clean-up"><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="False" ArrangeAttributes="True" ArrangeArgumentsStyle="True" /><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><HtmlReformatCode>True</HtmlReformatCode><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><PublicModifierStyleTs>True</PublicModifierStyleTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><OptimizeImportsTs>True</OptimizeImportsTs><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><XMLReformatCode>True</XMLReformatCode><CssAlphabetizeProperties>True</CssAlphabetizeProperties><CssReformatCode>True</CssReformatCode></Profile> 3 | Clean-up 4 | Clean-up 5 | True 6 | Required 7 | Required 8 | Required 9 | Required 10 | True 11 | False 12 | True 13 | True 14 | True 15 | True 16 | True 17 | False 18 | False 19 | True 20 | LINE_BREAK 21 | False 22 | True 23 | False 24 | CHOP_IF_LONG 25 | CHOP_ALWAYS 26 | True 27 | True 28 | True 29 | WRAP_IF_LONG 30 | 240 31 | CHOP_ALWAYS 32 | CHOP_ALWAYS 33 | CHOP_ALWAYS 34 | CHOP_ALWAYS 35 | CHOP_ALWAYS 36 | NEXT_LINE 37 | SEPARATE_LINES_FOR_NONSINGLE 38 | False 39 | div,p,form,h1,h2,h3 40 | True 41 | OnSingleLine 42 | html,thead,tbody,tfoot 43 | True 44 | ALIGN_ALL 45 | NEXT_LINE 46 | ALWAYS_ADD 47 | NEXT_LINE 48 | NEXT_LINE 49 | True 50 | True 51 | True 52 | True 53 | True 54 | LINE_BREAK 55 | LINE_BREAK 56 | True 57 | False 58 | NEXT_LINE 59 | WRAP_IF_LONG 60 | True 61 | LINE_BREAK 62 | WRAP_IF_LONG 63 | 240 64 | WRAP_IF_LONG 65 | CHOP_ALWAYS 66 | False 67 | 240 68 | False 69 | <?xml version="1.0" encoding="utf-16"?> 70 | <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> 71 | <TypePattern DisplayName="COM interfaces or structs"> 72 | <TypePattern.Match> 73 | <Or> 74 | <And> 75 | <Kind Is="Interface" /> 76 | <Or> 77 | <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> 78 | <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> 79 | </Or> 80 | </And> 81 | <Kind Is="Struct" /> 82 | </Or> 83 | </TypePattern.Match> 84 | </TypePattern> 85 | <TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All"> 86 | <TypePattern.Match> 87 | <And> 88 | <Kind Is="Class" /> 89 | <HasMember> 90 | <And> 91 | <Kind Is="Method" /> 92 | <HasAttribute Name="Xunit.FactAttribute" Inherited="True" /> 93 | </And> 94 | </HasMember> 95 | </And> 96 | </TypePattern.Match> 97 | <Entry DisplayName="Setup/Teardown Methods"> 98 | <Entry.Match> 99 | <Or> 100 | <Kind Is="Constructor" /> 101 | <And> 102 | <Kind Is="Method" /> 103 | <ImplementsInterface Name="System.IDisposable" /> 104 | </And> 105 | </Or> 106 | </Entry.Match> 107 | <Entry.SortBy> 108 | <Kind Order="Constructor" /> 109 | </Entry.SortBy> 110 | </Entry> 111 | <Entry DisplayName="All other members" /> 112 | <Entry Priority="100" DisplayName="Test Methods"> 113 | <Entry.Match> 114 | <And> 115 | <Kind Is="Method" /> 116 | <HasAttribute Name="Xunit.FactAttribute" /> 117 | </And> 118 | </Entry.Match> 119 | <Entry.SortBy> 120 | <Name /> 121 | </Entry.SortBy> 122 | </Entry> 123 | </TypePattern> 124 | <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"> 125 | <TypePattern.Match> 126 | <And> 127 | <Kind Is="Class" /> 128 | <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" /> 129 | </And> 130 | </TypePattern.Match> 131 | <Entry DisplayName="Setup/Teardown Methods"> 132 | <Entry.Match> 133 | <And> 134 | <Kind Is="Method" /> 135 | <Or> 136 | <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" /> 137 | <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" /> 138 | <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" /> 139 | <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" /> 140 | </Or> 141 | </And> 142 | </Entry.Match> 143 | </Entry> 144 | <Entry DisplayName="All other members" /> 145 | <Entry Priority="100" DisplayName="Test Methods"> 146 | <Entry.Match> 147 | <And> 148 | <Kind Is="Method" /> 149 | <HasAttribute Name="NUnit.Framework.TestAttribute" /> 150 | </And> 151 | </Entry.Match> 152 | <Entry.SortBy> 153 | <Name /> 154 | </Entry.SortBy> 155 | </Entry> 156 | </TypePattern> 157 | <TypePattern DisplayName="Default Pattern"> 158 | <Entry Priority="100" DisplayName="Public Delegates"> 159 | <Entry.Match> 160 | <And> 161 | <Access Is="Public" /> 162 | <Kind Is="Delegate" /> 163 | </And> 164 | </Entry.Match> 165 | <Entry.SortBy> 166 | <Name /> 167 | </Entry.SortBy> 168 | </Entry> 169 | <Entry Priority="100" DisplayName="Public Enums"> 170 | <Entry.Match> 171 | <And> 172 | <Access Is="Public" /> 173 | <Kind Is="Enum" /> 174 | </And> 175 | </Entry.Match> 176 | <Entry.SortBy> 177 | <Name /> 178 | </Entry.SortBy> 179 | </Entry> 180 | <Entry DisplayName="Static Fields and Constants"> 181 | <Entry.Match> 182 | <Or> 183 | <Kind Is="Constant" /> 184 | <And> 185 | <Kind Is="Field" /> 186 | <Static /> 187 | </And> 188 | </Or> 189 | </Entry.Match> 190 | <Entry.SortBy> 191 | <Kind Is="Member" /> 192 | <Name /> 193 | </Entry.SortBy> 194 | </Entry> 195 | <Entry DisplayName="Fields"> 196 | <Entry.Match> 197 | <And> 198 | <Kind Is="Field" /> 199 | <Not> 200 | <Static /> 201 | </Not> 202 | </And> 203 | </Entry.Match> 204 | <Entry.SortBy> 205 | <Name /> 206 | </Entry.SortBy> 207 | </Entry> 208 | <Entry DisplayName="Properties, Indexers"> 209 | <Entry.Match> 210 | <Or> 211 | <Kind Is="Property" /> 212 | <Kind Is="Indexer" /> 213 | </Or> 214 | </Entry.Match> 215 | </Entry> 216 | <Entry DisplayName="Constructors"> 217 | <Entry.Match> 218 | <Kind Is="Constructor" /> 219 | </Entry.Match> 220 | <Entry.SortBy> 221 | <Static /> 222 | </Entry.SortBy> 223 | </Entry> 224 | <Entry Priority="25" DisplayName="Interface Implementations"> 225 | <Entry.Match> 226 | <And> 227 | <Kind Is="Member" /> 228 | <ImplementsInterface /> 229 | </And> 230 | </Entry.Match> 231 | </Entry> 232 | <Entry DisplayName="All other members" /> 233 | <Entry DisplayName="Nested Types"> 234 | <Entry.Match> 235 | <Kind Is="Type" /> 236 | </Entry.Match> 237 | </Entry> 238 | </TypePattern> 239 | </Patterns> 240 | UseExplicitType 241 | UseVarWhenEvident 242 | UseExplicitType 243 | True 244 | False 245 | <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> 246 | <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> 247 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 248 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 249 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 250 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 251 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 252 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 253 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 254 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 255 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 256 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 257 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 258 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 259 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 260 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 261 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 262 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 263 | <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> 264 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 265 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 266 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 267 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 268 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 269 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 270 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 271 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 272 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 273 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 274 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 275 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 276 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 277 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 278 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 279 | <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> 280 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 281 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 282 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 283 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 284 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 285 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 286 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 287 | True 288 | True 289 | True 290 | True 291 | True 292 | True -------------------------------------------------------------------------------- /DecryptESD/DecryptESD.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp1.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /DecryptESD/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DecryptESD 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | Console.WriteLine("Hello World!"); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2017, Thomas Hounsell. 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Legacy/DecryptESD/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | https://key.bld.pm/xml/ 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Legacy/DecryptESD/CliOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Reflection; 4 | using CommandLine; 5 | using CommandLine.Text; 6 | 7 | namespace DecryptESD 8 | { 9 | public class CliOptions 10 | { 11 | [VerbOption("decrypt", HelpText = "Decrypt one or more ESD files")] 12 | public DecryptOptions DecryptVerb { get; set; } 13 | 14 | [VerbOption("update", HelpText = "Update the list of known RSA keys used for decrypting ESD files")] 15 | public UpdateOptions UpdateVerb { get; set; } 16 | 17 | public CliOptions() 18 | { 19 | DecryptVerb = new DecryptOptions(); 20 | UpdateVerb = new UpdateOptions(); 21 | } 22 | 23 | [HelpOption] 24 | public string GetUsage() 25 | { 26 | Assembly ass = Assembly.GetExecutingAssembly(); 27 | FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(ass.Location); 28 | 29 | HelpText ht = new HelpText 30 | { 31 | Heading = new HeadingInfo(fvi.FileDescription, ass.GetName().Version.ToString()), 32 | Copyright = new CopyrightInfo(fvi.CompanyName, DateTime.Today.Year), 33 | AddDashesToOption = true 34 | }; 35 | ht.AddOptions(this); 36 | return ht; 37 | } 38 | 39 | [HelpVerbOption] 40 | public string GetUsage(string verb) => HelpText.AutoBuild(this, verb); 41 | } 42 | 43 | public class DecryptOptions 44 | { 45 | [Option('k', "custom-key", HelpText = "A custom decryption key to use.")] 46 | public string CustomKey { get; set; } 47 | 48 | [OptionArray('f', "files", HelpText = "A list of ESD files to decrypt.", Required = true)] 49 | public string[] EsdFiles { get; set; } 50 | } 51 | 52 | public class UpdateOptions 53 | { 54 | [Option('f', "force", HelpText = "Overwrite the XML file with the current CryptoKey database rather than merge.")] 55 | public bool ForceUpdate { get; set; } 56 | 57 | [Option('u', "custom-url", HelpText = "A custom url to read the feed from.")] 58 | public string CustomUrl { get; set; } 59 | } 60 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/CryptoKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Reflection; 7 | using System.Xml.Linq; 8 | using DecryptESD.Properties; 9 | 10 | namespace DecryptESD 11 | { 12 | public class CryptoKey 13 | { 14 | private const string XML_FILE_NAME = "CryptoKeys.xml"; 15 | private static readonly string xmlFeedUrl = Settings.Default.XmlFeedURL; 16 | 17 | public int FirstBuild { get; } 18 | public byte[] Key { get; } 19 | public static CryptoKey[] Keys { get; private set; } 20 | 21 | 22 | public string KeyBase64 => Convert.ToBase64String(Key ?? new byte[] 23 | { 24 | }); 25 | 26 | private static string XmlPath => Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? "", XML_FILE_NAME); 27 | 28 | public CryptoKey(string firstBuild, string key) 29 | { 30 | FirstBuild = int.Parse(firstBuild); 31 | Key = Convert.FromBase64String(key); 32 | } 33 | 34 | public CryptoKey(int firstBuild, string key) 35 | { 36 | FirstBuild = firstBuild; 37 | Key = Convert.FromBase64String(key); 38 | } 39 | 40 | public static void LoadKeysFromXml() 41 | { 42 | using (FileStream fStr = new FileStream(XmlPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 43 | { 44 | XDocument xKeys = XDocument.Load(fStr); 45 | Keys = (from k in xKeys.Descendants("key") 46 | orderby int.Parse(k.Attribute("build").Value) 47 | select new CryptoKey(k.Attribute("build").Value, k.Attribute("value").Value)).ToArray(); 48 | } 49 | } 50 | 51 | public static void ReplaceXmlWithWebFeed() => ReplaceXmlWithWebFeed(xmlFeedUrl); 52 | 53 | public static void ReplaceXmlWithWebFeed(string url) 54 | { 55 | HttpWebRequest wreq = WebRequest.CreateHttp(url); 56 | 57 | using (HttpWebResponse wres = wreq.GetResponse() as HttpWebResponse) 58 | using (Stream str = wres.GetResponseStream()) 59 | using (FileStream fStr = new FileStream(XmlPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) 60 | { 61 | str.CopyTo(fStr); 62 | fStr.Flush(); 63 | } 64 | } 65 | 66 | public static void MergeWebFeedIntoXml() => MergeWebFeedIntoXml(xmlFeedUrl); 67 | 68 | public static void MergeWebFeedIntoXml(string url) 69 | { 70 | HttpWebRequest wreq = WebRequest.CreateHttp(url); 71 | 72 | using (HttpWebResponse wres = wreq.GetResponse() as HttpWebResponse) 73 | using (Stream str = wres.GetResponseStream()) 74 | using (FileStream fStr = new FileStream(XmlPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) 75 | { 76 | XDocument xCurrent = XDocument.Load(fStr); 77 | List ckCurrent = (from k in xCurrent.Descendants("key") 78 | orderby int.Parse(k.Attribute("build").Value) 79 | select new CryptoKey(k.Attribute("build").Value, k.Attribute("value").Value)).ToList(); 80 | 81 | XDocument xFeed = XDocument.Load(str); 82 | CryptoKey[] ckFeed = (from k in xFeed.Descendants("key") 83 | orderby int.Parse(k.Attribute("build").Value) 84 | select new CryptoKey(k.Attribute("build").Value, k.Attribute("value").Value)).ToArray(); 85 | 86 | foreach (CryptoKey ck in ckFeed) 87 | { 88 | if (ckCurrent.All(k => k.KeyBase64 != ck.KeyBase64)) 89 | { 90 | ckCurrent.Add(ck); 91 | } 92 | } 93 | 94 | 95 | XDocument xOutput = new XDocument(new XElement("keys", 96 | from r in ckCurrent 97 | select new XElement("key", new XAttribute("build", r.FirstBuild), new XAttribute("value", r.KeyBase64)))); 98 | 99 | fStr.Position = 0; 100 | fStr.SetLength(0); 101 | 102 | xOutput.Save(fStr); 103 | } 104 | } 105 | 106 | public static void UseCustomKey(string key) 107 | { 108 | Keys = new[] 109 | { 110 | new CryptoKey(0, key) 111 | }; 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/CryptoKeys.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Legacy/DecryptESD/DecryptESD.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C2500A05-8C18-47E8-B780-8C40CA471D20} 8 | Exe 9 | Properties 10 | DecryptESD 11 | DecryptESD 12 | v4.5 13 | 512 14 | true 15 | 16 | 17 | false 18 | publish\ 19 | true 20 | Disk 21 | false 22 | Foreground 23 | 7 24 | Days 25 | false 26 | false 27 | true 28 | 0 29 | 0.2.0.%2a 30 | false 31 | true 32 | 33 | 34 | AnyCPU 35 | true 36 | full 37 | false 38 | bin\Debug\ 39 | DEBUG;TRACE 40 | prompt 41 | 4 42 | true 43 | false 44 | 45 | 46 | AnyCPU 47 | pdbonly 48 | true 49 | bin\Release\ 50 | TRACE 51 | prompt 52 | 4 53 | true 54 | false 55 | 56 | 57 | false 58 | 59 | 60 | 11A2929FE3E540CFFE2AE1FC916AD0041F15EFDF 61 | 62 | 63 | true 64 | 65 | 66 | DecryptESD.snk 67 | 68 | 69 | http://timestamp.globalsign.com/scripts/timestamp.dll 70 | 71 | 72 | 73 | ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll 74 | True 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | True 100 | True 101 | Settings.settings 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | SettingsSingleFileGenerator 110 | Settings.Designer.cs 111 | 112 | 113 | 114 | 115 | Always 116 | 117 | 118 | 119 | 120 | False 121 | Microsoft .NET Framework 4.6 %28x86 and x64%29 122 | true 123 | 124 | 125 | False 126 | .NET Framework 3.5 SP1 127 | false 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 142 | -------------------------------------------------------------------------------- /Legacy/DecryptESD/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DecryptESD 4 | { 5 | public class NoValidCryptoKeyException : Exception 6 | { 7 | } 8 | 9 | public class UnencryptedImageException : Exception 10 | { 11 | } 12 | 13 | public class NoImageKeyException : Exception 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/IntegrityTable.cs: -------------------------------------------------------------------------------- 1 | namespace DecryptESD.IO 2 | { 3 | public class IntegrityTable 4 | { 5 | public IntegrityTableHeader Header { get; } 6 | public byte[][] Hashes { get; } 7 | 8 | public IntegrityTable(IntegrityTableHeader header, byte[][] hashes) 9 | { 10 | Header = header; 11 | Hashes = hashes; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/IntegrityTableHeader.cs: -------------------------------------------------------------------------------- 1 | namespace DecryptESD.IO 2 | { 3 | public struct IntegrityTableHeader 4 | { 5 | public uint TableSize; 6 | public uint TableRowCount; 7 | public uint ChunkSize; 8 | } 9 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/ResourceHeader.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace DecryptESD.IO 4 | { 5 | [StructLayout(LayoutKind.Explicit, Size = 24)] 6 | public struct ResourceHeader 7 | { 8 | [FieldOffset(0)] 9 | public ulong SizeInWimWithFlags; 10 | 11 | [FieldOffset(7)] 12 | public ResourceHeaderFlags Flags; 13 | 14 | [FieldOffset(8)] 15 | public long OffsetInWim; 16 | 17 | [FieldOffset(16)] 18 | public ulong OriginalSize; 19 | 20 | public ulong SizeInWim => SizeInWimWithFlags & 0xFFFFFFFFFFFFFF; 21 | } 22 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/ResourceHeaderFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DecryptESD.IO 4 | { 5 | [Flags] 6 | public enum ResourceHeaderFlags : byte 7 | { 8 | Free = 0x1, 9 | Metadata = 0x2, 10 | Compressed = 0x4, 11 | Spanned = 0x8 12 | } 13 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/WimFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | using System.Xml; 8 | using System.Xml.Linq; 9 | 10 | namespace DecryptESD.IO 11 | { 12 | public class WimFile : IDisposable 13 | { 14 | private readonly FileStream _file; 15 | private readonly BinaryReader _reader; 16 | private readonly BinaryWriter _writer; 17 | 18 | public int BuildNumber => int.Parse(XmlMetadata.Descendants("BUILD").LastOrDefault()?.Value ?? "0"); 19 | 20 | public WimHeader Header { get; private set; } 21 | public IntegrityTable IntegrityTable { get; private set; } 22 | public XElement XmlEsdMetadata { get; private set; } 23 | public XDocument XmlMetadata { get; private set; } 24 | 25 | public WimFile(string path) 26 | { 27 | _file = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); 28 | _reader = new BinaryReader(_file, Encoding.Unicode, true); 29 | _writer = new BinaryWriter(_file, Encoding.Unicode, true); 30 | 31 | ReadWimHeader(); 32 | ReadXmlMetadata(); 33 | ReadIntegrityTable(); 34 | } 35 | 36 | public void Dispose() 37 | { 38 | _writer.Flush(); 39 | 40 | _reader.Dispose(); 41 | _writer.Dispose(); 42 | _file.Dispose(); 43 | } 44 | 45 | private unsafe void ReadWimHeader() 46 | { 47 | _file.Position = 0; 48 | 49 | byte[] bHeader = _reader.ReadBytes(sizeof(WimHeader)); 50 | fixed (byte* pHeader = bHeader) 51 | { 52 | Header = (WimHeader)Marshal.PtrToStructure((IntPtr)pHeader, typeof(WimHeader)); 53 | } 54 | } 55 | 56 | private void ReadXmlMetadata() 57 | { 58 | _file.Position = Header.XmlData.OffsetInWim; 59 | 60 | byte[] bXml = _reader.ReadBytes((int)Header.XmlData.SizeInWim); 61 | using (MemoryStream mStr = new MemoryStream(bXml)) 62 | { 63 | XmlMetadata = XDocument.Load(mStr); 64 | } 65 | } 66 | 67 | private unsafe void ReadIntegrityTable() 68 | { 69 | _file.Position = Header.IntegrityTable.OffsetInWim; 70 | 71 | byte[] bTable = _reader.ReadBytes(sizeof(IntegrityTableHeader)); 72 | IntegrityTableHeader itHeader; 73 | fixed (byte* pTable = bTable) 74 | { 75 | itHeader = (IntegrityTableHeader)Marshal.PtrToStructure((IntPtr)pTable, typeof(IntegrityTableHeader)); 76 | } 77 | 78 | var bbHashes = new byte[itHeader.TableRowCount][]; 79 | for (int i = 0; i < bbHashes.Length; i++) 80 | { 81 | bbHashes[i] = _reader.ReadBytes(20); 82 | } 83 | 84 | IntegrityTable = new IntegrityTable(itHeader, bbHashes); 85 | } 86 | 87 | public void DecryptEsd() 88 | { 89 | XmlEsdMetadata = XmlMetadata.Root?.Element("ESD"); 90 | if (XmlEsdMetadata == null) 91 | { 92 | throw new UnencryptedImageException(); 93 | } 94 | 95 | string b64AesKey = XmlEsdMetadata.Element("KEY")?.Value; 96 | if (string.IsNullOrEmpty(b64AesKey)) 97 | { 98 | throw new NoImageKeyException(); 99 | } 100 | 101 | byte[] bAesKey = Convert.FromBase64String(b64AesKey); 102 | 103 | bool success = false; 104 | foreach (byte[] cryptoKey in from k in CryptoKey.Keys 105 | orderby Math.Abs(k.FirstBuild - BuildNumber) 106 | select k.Key) 107 | { 108 | try 109 | { 110 | using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) 111 | { 112 | rsa.ImportCspBlob(cryptoKey); 113 | bAesKey = rsa.Decrypt(bAesKey, true); 114 | } 115 | } 116 | catch (CryptographicException) 117 | { 118 | continue; 119 | } 120 | 121 | success = true; 122 | break; 123 | } 124 | 125 | if (!success) 126 | { 127 | throw new NoValidCryptoKeyException(); 128 | } 129 | 130 | foreach (XElement range in XmlEsdMetadata.Descendants("RANGE")) 131 | { 132 | int rangeLength = int.Parse(range.Attribute("Bytes").Value); 133 | long rangeOffset = long.Parse(range.Attribute("Offset").Value); 134 | 135 | _file.Position = rangeOffset; 136 | int bEncryptedSize = (rangeLength / 16 + 1) * 16; 137 | byte[] bEncrypted = _reader.ReadBytes(bEncryptedSize); 138 | 139 | using (AesCryptoServiceProvider aesCipher = new AesCryptoServiceProvider 140 | { 141 | Key = bAesKey, 142 | IV = Convert.FromBase64String("AAAAAAAAAAAAAAAAAAAAAA=="), 143 | Mode = CipherMode.CBC, 144 | Padding = PaddingMode.None 145 | }) 146 | using (MemoryStream msEncrypted = new MemoryStream(bEncrypted)) 147 | using (CryptoStream strCrypto = new CryptoStream(msEncrypted, aesCipher.CreateDecryptor(), CryptoStreamMode.Read)) 148 | { 149 | var bDecrypted = new byte[bEncryptedSize - 16]; 150 | strCrypto.Read(bDecrypted, 0, bDecrypted.Length); 151 | 152 | _file.Position = rangeOffset; 153 | _file.Write(bDecrypted, 0, bDecrypted.Length); 154 | _file.Flush(); 155 | } 156 | } 157 | 158 | XmlEsdMetadata.Remove(); 159 | 160 | WriteXmlMetadata(); 161 | WriteIntegrityTable(); 162 | WriteWimHeader(); 163 | } 164 | 165 | private void WriteXmlMetadata() 166 | { 167 | byte[] bXml; 168 | using (MemoryStream msXml = new MemoryStream()) 169 | { 170 | using (XmlWriter xw = XmlWriter.Create(msXml, 171 | new XmlWriterSettings 172 | { 173 | OmitXmlDeclaration = true, 174 | Encoding = Encoding.Unicode 175 | })) 176 | { 177 | XmlMetadata.Save(xw); 178 | } 179 | 180 | long xmlSize = msXml.Length; 181 | 182 | long fileSize = xmlSize + Header.XmlData.OffsetInWim + (long)Header.IntegrityTable.SizeInWim; 183 | XmlMetadata.Root?.Element("TOTALBYTES")?.SetValue(fileSize.ToString()); 184 | 185 | msXml.Position = 0; 186 | msXml.SetLength(0); 187 | using (XmlWriter xw = XmlWriter.Create(msXml, 188 | new XmlWriterSettings 189 | { 190 | OmitXmlDeclaration = true, 191 | Encoding = Encoding.Unicode 192 | })) 193 | { 194 | XmlMetadata.Save(xw); 195 | } 196 | 197 | bXml = msXml.ToArray(); 198 | } 199 | 200 | WimHeader whUpdated = Header; 201 | whUpdated.XmlData.OriginalSize = (ulong)bXml.LongLength; 202 | whUpdated.XmlData.SizeInWimWithFlags = (ulong)bXml.LongLength | ((ulong)whUpdated.XmlData.Flags << 56); 203 | 204 | _file.Position = whUpdated.XmlData.OffsetInWim; 205 | _file.SetLength(whUpdated.XmlData.OffsetInWim); 206 | _writer.Write(bXml); 207 | 208 | whUpdated.IntegrityTable.OffsetInWim = _file.Position; 209 | Header = whUpdated; 210 | } 211 | 212 | private unsafe void WriteIntegrityTable() 213 | { 214 | _file.Position = Header.IntegrityTable.OffsetInWim; 215 | 216 | foreach (XElement range in XmlEsdMetadata.Descendants("RANGE")) 217 | { 218 | int rangeLength = int.Parse(range.Attribute("Bytes").Value); 219 | long rangeOffset = long.Parse(range.Attribute("Offset").Value); 220 | 221 | long chunkStart = rangeOffset - sizeof(WimHeader); 222 | long chunkStartNum = chunkStart / IntegrityTable.Header.ChunkSize; 223 | long chunkEnd = rangeOffset + rangeLength - sizeof(WimHeader); 224 | long chunkEndNum = chunkEnd / IntegrityTable.Header.ChunkSize; 225 | 226 | 227 | using (SHA1 sha = SHA1.Create()) 228 | { 229 | for (long i = chunkStartNum; i <= chunkEndNum; i++) 230 | { 231 | _file.Position = sizeof(WimHeader) + i * IntegrityTable.Header.ChunkSize; 232 | 233 | int chunkSize = _file.Position + IntegrityTable.Header.ChunkSize > Header.XmlData.OffsetInWim 234 | ? (int)(Header.XmlData.OffsetInWim - _file.Position) 235 | : (int)IntegrityTable.Header.ChunkSize; 236 | 237 | byte[] data = _reader.ReadBytes(chunkSize); 238 | 239 | IntegrityTable.Hashes[i] = sha.ComputeHash(data, 0, data.Length); 240 | } 241 | } 242 | } 243 | 244 | _file.Position = Header.IntegrityTable.OffsetInWim; 245 | var bItHeader = new byte[sizeof(IntegrityTableHeader)]; 246 | IntegrityTableHeader ith = IntegrityTable.Header; 247 | Marshal.Copy((IntPtr)(&ith), bItHeader, 0, bItHeader.Length); 248 | _writer.Write(bItHeader); 249 | 250 | foreach (byte[] b in IntegrityTable.Hashes) 251 | { 252 | _writer.Write(b); 253 | } 254 | } 255 | 256 | private unsafe void WriteWimHeader() 257 | { 258 | WimHeader whUpdated = Header; 259 | var bWhUpdated = new byte[sizeof(WimHeader)]; 260 | Marshal.Copy((IntPtr)(&whUpdated), bWhUpdated, 0, bWhUpdated.Length); 261 | _file.Position = 0; 262 | _writer.Write(bWhUpdated); 263 | } 264 | } 265 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/WimHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace DecryptESD.IO 5 | { 6 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 7 | public unsafe struct WimHeader 8 | { 9 | public fixed byte Magic [8]; 10 | public uint HeaderSize; 11 | public uint WimVersion; 12 | public WimHeaderFlags WimFlags; 13 | public uint ChunkSize; 14 | public Guid WimGuid; 15 | public ushort PartNumber; 16 | public ushort TotalParts; 17 | public uint ImageCount; 18 | public ResourceHeader LookupTable; 19 | public ResourceHeader XmlData; 20 | public ResourceHeader BootMetadata; 21 | public uint BootIndex; 22 | public ResourceHeader IntegrityTable; 23 | public fixed byte Unused [60]; 24 | } 25 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/IO/WimHeaderFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DecryptESD.IO 4 | { 5 | [Flags] 6 | public enum WimHeaderFlags : uint 7 | { 8 | None = 0, 9 | Reserved = 1, 10 | Compressed = 2, 11 | ReadOnly = 4, 12 | Spanned = 8, 13 | ResourcesOnly = 0x10, 14 | MetadataOnly = 0x20, 15 | WriteInProgress = 0x40, 16 | ReparsePointFixup = 0x80, 17 | 18 | CompressReserved = 0x10000, 19 | CompressXpress = 0x20000, 20 | CompressLzx = 0x40000, 21 | CompressLzms = 0x80000, 22 | 23 | CompressXpress2 = 0x200000 24 | } 25 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using CommandLine; 4 | using DecryptESD.IO; 5 | 6 | namespace DecryptESD 7 | { 8 | internal class Program 9 | { 10 | public static object Options; 11 | public static string OptionVerb; 12 | 13 | private static void Main(string[] args) 14 | { 15 | CliOptions baseOptions = new CliOptions(); 16 | if (!Parser.Default.ParseArguments(args, 17 | baseOptions, 18 | (s, o) => 19 | { 20 | OptionVerb = s; 21 | Options = o; 22 | })) 23 | { 24 | Environment.Exit(Parser.DefaultExitCodeFail); 25 | } 26 | 27 | 28 | switch (OptionVerb) 29 | { 30 | case "decrypt": 31 | { 32 | DecryptEsd((DecryptOptions)Options); 33 | break; 34 | } 35 | 36 | case "update": 37 | { 38 | UpdateKeys((UpdateOptions)Options); 39 | break; 40 | } 41 | } 42 | } 43 | 44 | private static void DecryptEsd(DecryptOptions options) 45 | { 46 | if (string.IsNullOrEmpty(options.CustomKey)) 47 | { 48 | CryptoKey.LoadKeysFromXml(); 49 | } 50 | else 51 | { 52 | try 53 | { 54 | CryptoKey.UseCustomKey(options.CustomKey); 55 | } 56 | catch (FormatException) 57 | { 58 | Console.WriteLine("The key you have specified is not valid. Loading the keys from the XML file instead..."); 59 | CryptoKey.LoadKeysFromXml(); 60 | } 61 | } 62 | 63 | foreach (string file in options.EsdFiles) 64 | { 65 | if (File.Exists(file)) 66 | { 67 | try 68 | { 69 | using (WimFile wf = new WimFile(file)) 70 | { 71 | wf.DecryptEsd(); 72 | } 73 | } 74 | catch (NoValidCryptoKeyException) 75 | { 76 | Console.WriteLine($"We could not find the correct CryptoKey for \"{file}\"."); 77 | } 78 | catch (UnencryptedImageException) 79 | { 80 | Console.WriteLine($"You are trying to decrypt \"{file}\", but it is already decrypted."); 81 | } 82 | } 83 | else 84 | { 85 | Console.WriteLine($"The file \"{file}\" does not exist."); 86 | } 87 | } 88 | } 89 | 90 | private static void UpdateKeys(UpdateOptions options) 91 | { 92 | if (string.IsNullOrEmpty(options.CustomUrl)) 93 | { 94 | if (options.ForceUpdate) 95 | { 96 | CryptoKey.ReplaceXmlWithWebFeed(); 97 | } 98 | else 99 | { 100 | CryptoKey.MergeWebFeedIntoXml(); 101 | } 102 | } 103 | else 104 | { 105 | if (options.ForceUpdate) 106 | { 107 | CryptoKey.ReplaceXmlWithWebFeed(options.CustomUrl); 108 | } 109 | else 110 | { 111 | CryptoKey.MergeWebFeedIntoXml(options.CustomUrl); 112 | } 113 | } 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /Legacy/DecryptESD/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("DecryptESD")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("Thomas Hounsell")] 13 | [assembly: AssemblyProduct("DecryptESD")] 14 | [assembly: AssemblyCopyright("Copyright © 2016, Thomas Hounsell")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("c2500a05-8c18-47e8-b780-8c40ca471d20")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("0.4.0.*")] 37 | [assembly: AssemblyFileVersion("0.4.0.0")] 38 | [assembly: NeutralResourcesLanguage("en-GB")] 39 | 40 | -------------------------------------------------------------------------------- /Legacy/DecryptESD/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DecryptESD.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("https://key.bld.pm/xml/")] 29 | public string XmlFeedURL { 30 | get { 31 | return ((string)(this["XmlFeedURL"])); 32 | } 33 | set { 34 | this["XmlFeedURL"] = value; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Legacy/DecryptESD/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | https://key.bld.pm/xml/ 7 | 8 | 9 | -------------------------------------------------------------------------------- /Legacy/DecryptESD/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WIMCore 2 | WIMCore is a library for the reading and writing of Windows Image files (WIM). 3 | 4 | ## DecryptESD 5 | Remove encryption from the ESD files distributed through the Windows Store infrastructure with DecryptESD. 6 | 7 | DecryptESD currently targets .NET Core 1.1. 8 | 9 | A legacy version is available that uses .NET Framework 4.5, allowing it to be used back to Windows Vista SP2. Compatibility with the latest versions of Mono as of DecryptESD v0.3.2 has been confirmed on both Linux and OS X. 10 | 11 | ## Current State 12 | * Currently being rewritten to use the current version of the .NET Core Framework. 13 | * Unit tests are being added to the rewritten .NET Core version. 14 | * .NET Core Rewrite also adds more generalised WIM library support in a new "WIMCore" Library. 15 | * This new rewrite also adds a lot more sanity checks and error handling. 16 | 17 | ## Current State (Legacy version) 18 | * ESDs are decrypted successfully, both pre-14361 and post-14361. 19 | * ESDs will be almost identical byte-for-byte to esddecrypt output - the only differences will be due to DecryptESD dropping indentation in the XML data, which is what DISM does. 20 | * XML and Integrity tables are corrected after decryption 21 | 22 | ## Future plans 23 | * Localise into other languages 24 | 25 | ## Changelog (Legacy) 26 | * v0.4.0 27 | * Allow update from a remote feed. 28 | * Defaults to new CryptoKey website XML feed, provided via BuildFeed team. Alternate feeds can be set via config or command argument. 29 | * Add command verbs `update` and `decrypt` to separate existing and new functionality. 30 | 31 | * v0.3.2 32 | * No longer crash on already decrypted ESD - just skip it. 33 | * Add 14371 ESD key. 34 | * Swap from RijndaelManaged to AesCryptoServiceProvider for decryption. 35 | * This uses native APIs rather than the pure managed code implementation. 36 | * It is believed to use AES-NI instructions on supporting hardware on Windows. 37 | 38 | * v0.3.1 39 | * Test all keys, not just "best" key - but favour the closest key in build number. 40 | * Add 14342 multi ESD key. 41 | * Reduce requirement to .NET Framework 4.5, down from 4.5.2. 42 | 43 | * v0.3 44 | * Add basic command line switches. 45 | * Support for multiple ESDs in batch. 46 | * Some basic error handling. 47 | * Allow specifying a key via a command line switch. 48 | 49 | * v0.2 50 | * Fix XML metadata. 51 | * Fix Integrity table. 52 | 53 | * v0.1 54 | * Initial release. 55 | 56 | ## License 57 | Copyright © 2017, Thomas Hounsell. 58 | 59 | All rights reserved. 60 | 61 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 62 | 63 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 64 | 65 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 66 | 67 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 68 | 69 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 70 | -------------------------------------------------------------------------------- /WIMCore.Tests/IntegrityTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using WIMCore.Exceptions; 4 | 5 | namespace WIMCore.Tests 6 | { 7 | [TestClass] 8 | public class IntegrityTests 9 | { 10 | [TestMethod] 11 | public void CheckIntegrityWithNoIntegrityData() 12 | { 13 | WimIntegrityException ex = Assert.ThrowsException(() => 14 | { 15 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-CompressNone.wim")) 16 | { 17 | bool succcess = wf.CheckIntegrity(); 18 | } 19 | }); 20 | 21 | Assert.AreEqual(WimIntegrityExceptionType.NoIntegrityData, ex.Type); 22 | } 23 | 24 | [TestMethod] 25 | public void LoadWin10WithIntegrityAndCheck() 26 | { 27 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-Integrity.wim")) 28 | { 29 | bool success = wf.CheckIntegrity(); 30 | Assert.IsTrue(success); 31 | } 32 | } 33 | 34 | [TestMethod] 35 | public void LoadWin10WithBrokenIntegrityAndCheck() 36 | { 37 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-BrokenIntegrity.wim")) 38 | { 39 | bool success = wf.CheckIntegrity(); 40 | Assert.IsTrue(!success); 41 | } 42 | } 43 | 44 | [TestMethod] 45 | public void LoadWin10MultipleImagesWithIntegrityAndCheck() 46 | { 47 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-MultiImage-Integrity.wim")) 48 | { 49 | Assert.IsTrue(wf.ImageCount == 2); 50 | 51 | bool success = wf.CheckIntegrity(); 52 | Assert.IsTrue(success); 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /WIMCore.Tests/LoadTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using WIMCore.Exceptions; 4 | 5 | namespace WIMCore.Tests 6 | { 7 | [TestClass] 8 | public class LoadTests 9 | { 10 | [TestMethod] 11 | public void LoadInvalidSizeWithError() 12 | { 13 | WimInvalidException wnvex = Assert.ThrowsException(() => 14 | { 15 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Error-InvalidSize.wim")) 16 | { 17 | } 18 | }); 19 | 20 | Assert.AreEqual(WimInvalidExceptionType.InvalidSize, wnvex.Type); 21 | } 22 | 23 | [TestMethod] 24 | public void LoadInvalidMagicWithError() 25 | { 26 | WimInvalidException wnvex = Assert.ThrowsException(() => 27 | { 28 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Error-InvalidMagic.wim")) 29 | { 30 | } 31 | }); 32 | 33 | Assert.AreEqual(WimInvalidExceptionType.InvalidMagic, wnvex.Type); 34 | } 35 | 36 | [TestMethod] 37 | public void LoadWin10Rs1CompressNone() 38 | { 39 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-CompressNone.wim")) 40 | { 41 | wf.LoadImageMetadata(); 42 | Assert.IsTrue((wf.Flags & WimHeaderFlags.Compressed) == 0); 43 | } 44 | } 45 | 46 | [TestMethod] 47 | public void LoadWin10Rs1CompressFast() 48 | { 49 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-CompressFast.wim")) 50 | { 51 | wf.LoadImageMetadata(); 52 | Assert.IsTrue((wf.Flags & WimHeaderFlags.CompressXpress) > 0); 53 | } 54 | } 55 | 56 | [TestMethod] 57 | public void LoadWin10Rs1CompressMax() 58 | { 59 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-CompressMax.wim")) 60 | { 61 | wf.LoadImageMetadata(); 62 | Assert.IsTrue((wf.Flags & WimHeaderFlags.CompressLzx) > 0); 63 | } 64 | } 65 | 66 | [TestMethod] 67 | public void LoadWin10Rs1MultipleImages() 68 | { 69 | using (WimFile wf = new WimFile($"{AppContext.BaseDirectory}\\TestFiles\\Win10-RS1-MultiImage-Integrity.wim")) 70 | { 71 | wf.LoadImageMetadata(); 72 | Assert.IsTrue(wf.ImageCount == 2); 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Error-InvalidMagic.wim: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Error-InvalidSize.wim: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Win10-RS1-BrokenIntegrity.wim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hounsell/DecryptESD/f64f39fd6637c4667fd9ba8dbcd087c21cfb75f7/WIMCore.Tests/TestFiles/Win10-RS1-BrokenIntegrity.wim -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Win10-RS1-CompressFast.wim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hounsell/DecryptESD/f64f39fd6637c4667fd9ba8dbcd087c21cfb75f7/WIMCore.Tests/TestFiles/Win10-RS1-CompressFast.wim -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Win10-RS1-CompressMax.wim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hounsell/DecryptESD/f64f39fd6637c4667fd9ba8dbcd087c21cfb75f7/WIMCore.Tests/TestFiles/Win10-RS1-CompressMax.wim -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Win10-RS1-CompressNone.wim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hounsell/DecryptESD/f64f39fd6637c4667fd9ba8dbcd087c21cfb75f7/WIMCore.Tests/TestFiles/Win10-RS1-CompressNone.wim -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Win10-RS1-Integrity.wim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hounsell/DecryptESD/f64f39fd6637c4667fd9ba8dbcd087c21cfb75f7/WIMCore.Tests/TestFiles/Win10-RS1-Integrity.wim -------------------------------------------------------------------------------- /WIMCore.Tests/TestFiles/Win10-RS1-MultiImage-Integrity.wim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hounsell/DecryptESD/f64f39fd6637c4667fd9ba8dbcd087c21cfb75f7/WIMCore.Tests/TestFiles/Win10-RS1-MultiImage-Integrity.wim -------------------------------------------------------------------------------- /WIMCore.Tests/WIMCore.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp1.1 5 | 6 | 7 | 8 | False 9 | 10 | 11 | 12 | False 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Always 29 | 30 | 31 | Always 32 | 33 | 34 | Always 35 | 36 | 37 | Always 38 | 39 | 40 | Always 41 | 42 | 43 | Always 44 | 45 | 46 | Always 47 | 48 | 49 | Always 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | Always 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /WIMCore/Compression/LzmsStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace WIMCore.Compression 5 | { 6 | public class LzmsStream : Stream 7 | { 8 | public override bool CanRead { get; } 9 | public override bool CanSeek { get; } 10 | public override bool CanWrite { get; } 11 | public override long Length { get; } 12 | public override long Position { get; set; } 13 | 14 | public override void Flush() 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | 19 | public override int Read(byte[] buffer, int offset, int count) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | 24 | public override long Seek(long offset, SeekOrigin origin) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | 29 | public override void SetLength(long value) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | 34 | public override void Write(byte[] buffer, int offset, int count) 35 | { 36 | throw new NotImplementedException(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /WIMCore/Compression/LzxStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace WIMCore.Compression 5 | { 6 | public class LzxStream : Stream 7 | { 8 | public override bool CanRead { get; } 9 | public override bool CanSeek { get; } 10 | public override bool CanWrite { get; } 11 | public override long Length { get; } 12 | public override long Position { get; set; } 13 | 14 | public override void Flush() 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | 19 | public override int Read(byte[] buffer, int offset, int count) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | 24 | public override long Seek(long offset, SeekOrigin origin) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | 29 | public override void SetLength(long value) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | 34 | public override void Write(byte[] buffer, int offset, int count) 35 | { 36 | throw new NotImplementedException(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /WIMCore/Compression/XpressStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace WIMCore.Compression 5 | { 6 | public class XpressStream : Stream 7 | { 8 | public override bool CanRead { get; } 9 | public override bool CanSeek { get; } 10 | public override bool CanWrite { get; } 11 | public override long Length { get; } 12 | public override long Position { get; set; } 13 | 14 | public override void Flush() 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | 19 | public override int Read(byte[] buffer, int offset, int count) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | 24 | public override long Seek(long offset, SeekOrigin origin) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | 29 | public override void SetLength(long value) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | 34 | public override void Write(byte[] buffer, int offset, int count) 35 | { 36 | throw new NotImplementedException(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /WIMCore/DirectoryEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace WIMCore 4 | { 5 | [StructLayout(LayoutKind.Explicit, Size = 102)] 6 | public unsafe struct DirectoryEntry 7 | { 8 | [FieldOffset(0)] 9 | public ulong EntryLength; 10 | 11 | [FieldOffset(8)] 12 | public uint Attributes; 13 | 14 | [FieldOffset(12)] 15 | public uint SecurityId; 16 | 17 | [FieldOffset(16)] 18 | public ulong SubDirectoryOffset; 19 | 20 | [FieldOffset(24)] 21 | public ulong Reserved1; 22 | 23 | [FieldOffset(32)] 24 | public ulong Reserved2; 25 | 26 | [FieldOffset(40)] 27 | public ulong CreationTime; 28 | 29 | [FieldOffset(48)] 30 | public ulong LastAccessTime; 31 | 32 | [FieldOffset(56)] 33 | public ulong LastWriteTime; 34 | 35 | [FieldOffset(64)] 36 | public fixed byte Hash [20]; 37 | 38 | [FieldOffset(88)] 39 | public uint ReparseTag; 40 | 41 | [FieldOffset(92)] 42 | public ushort ReparseReserved; 43 | 44 | [FieldOffset(94)] 45 | public ushort ReparseFlags; 46 | 47 | [FieldOffset(88)] 48 | public ulong HardLink; 49 | 50 | [FieldOffset(96)] 51 | public ushort Streams; 52 | 53 | [FieldOffset(98)] 54 | public ushort ShortFileNameLength; 55 | 56 | [FieldOffset(100)] 57 | public ushort FileNameLength; 58 | } 59 | } -------------------------------------------------------------------------------- /WIMCore/DirectoryTableEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace WIMCore 4 | { 5 | public class DirectoryTableEntry 6 | { 7 | public string Name { get; } 8 | public DirectoryEntry Entry { get; } 9 | 10 | public Dictionary AlternateStreams { get; } 11 | 12 | public DirectoryTableEntry(string name, DirectoryEntry entry, Dictionary alternateStreams) 13 | { 14 | Name = name; 15 | Entry = entry; 16 | AlternateStreams = alternateStreams; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /WIMCore/Exceptions/WimIntegrityException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WIMCore.Exceptions 4 | { 5 | public class WimIntegrityException : Exception 6 | { 7 | public WimIntegrityExceptionType Type { get; } 8 | 9 | public WimIntegrityException(WimIntegrityExceptionType type) 10 | { 11 | Type = type; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WIMCore/Exceptions/WimIntegrityExceptionType.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore.Exceptions 2 | { 3 | public enum WimIntegrityExceptionType 4 | { 5 | NoIntegrityData 6 | } 7 | } -------------------------------------------------------------------------------- /WIMCore/Exceptions/WimInvalidException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WIMCore.Exceptions 4 | { 5 | public class WimInvalidException : Exception 6 | { 7 | public WimInvalidExceptionType Type { get; } 8 | 9 | public WimInvalidException(WimInvalidExceptionType type) 10 | { 11 | Type = type; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WIMCore/Exceptions/WimInvalidExceptionType.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore.Exceptions 2 | { 3 | public enum WimInvalidExceptionType 4 | { 5 | InvalidSize, 6 | InvalidMagic 7 | } 8 | } -------------------------------------------------------------------------------- /WIMCore/IntegrityTable.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public class IntegrityTable 4 | { 5 | public IntegrityTableHeader Header { get; } 6 | public byte[][] Hashes { get; } 7 | 8 | public IntegrityTable(IntegrityTableHeader header, byte[][] hashes) 9 | { 10 | Header = header; 11 | Hashes = hashes; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WIMCore/IntegrityTableHeader.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public struct IntegrityTableHeader 4 | { 5 | public uint TableSize; 6 | public uint TableRowCount; 7 | public uint ChunkSize; 8 | } 9 | } -------------------------------------------------------------------------------- /WIMCore/LookupEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace WIMCore 4 | { 5 | [StructLayout(LayoutKind.Explicit, Size = 50)] 6 | public unsafe struct LookupEntry 7 | { 8 | [FieldOffset(0)] 9 | public ulong SizeInWimWithFlags; 10 | 11 | [FieldOffset(7)] 12 | public ResourceHeaderFlags Flags; 13 | 14 | [FieldOffset(8)] 15 | public long OffsetInWim; 16 | 17 | [FieldOffset(16)] 18 | public ulong OriginalSize; 19 | 20 | [FieldOffset(24)] 21 | public ushort PartNumber; 22 | 23 | [FieldOffset(26)] 24 | public uint ReferenceCount; 25 | 26 | [FieldOffset(30)] 27 | public fixed byte Hash [20]; 28 | 29 | public ulong SizeInWim => SizeInWimWithFlags & 0xFFFFFFFFFFFFFF; 30 | } 31 | } -------------------------------------------------------------------------------- /WIMCore/LookupTable.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public class LookupTable 4 | { 5 | public LookupEntry[] Entries { get; } 6 | 7 | public LookupTable(LookupEntry[] entries) 8 | { 9 | Entries = entries; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /WIMCore/ResourceHeader.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace WIMCore 4 | { 5 | [StructLayout(LayoutKind.Explicit, Size = 24)] 6 | public struct ResourceHeader 7 | { 8 | [FieldOffset(0)] 9 | public ulong SizeInWimWithFlags; 10 | 11 | [FieldOffset(7)] 12 | public ResourceHeaderFlags Flags; 13 | 14 | [FieldOffset(8)] 15 | public long OffsetInWim; 16 | 17 | [FieldOffset(16)] 18 | public ulong OriginalSize; 19 | 20 | public ulong SizeInWim => SizeInWimWithFlags & 0xFFFFFFFFFFFFFF; 21 | } 22 | } -------------------------------------------------------------------------------- /WIMCore/ResourceHeaderFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WIMCore 4 | { 5 | [Flags] 6 | public enum ResourceHeaderFlags : byte 7 | { 8 | Free = 0x1, 9 | Metadata = 0x2, 10 | Compressed = 0x4, 11 | Spanned = 0x8 12 | } 13 | } -------------------------------------------------------------------------------- /WIMCore/SecurityTable.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public class SecurityTable 4 | { 5 | public SecurityTableHeader Header { get; } 6 | public byte[][] Descriptors { get; } 7 | 8 | public SecurityTable(SecurityTableHeader header, byte[][] descriptors) 9 | { 10 | Header = header; 11 | Descriptors = descriptors; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /WIMCore/SecurityTableHeader.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public struct SecurityTableHeader 4 | { 5 | public uint TotalLength; 6 | public uint EntryCount; 7 | } 8 | } -------------------------------------------------------------------------------- /WIMCore/StreamEntry.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public unsafe struct StreamEntry 4 | { 5 | public ulong Length; 6 | public ulong Reserved1; 7 | public fixed byte Hash [20]; 8 | public ushort StreamNameLength; 9 | } 10 | } -------------------------------------------------------------------------------- /WIMCore/WIMCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.3 5 | 6 | 7 | 8 | True 9 | 10 | 11 | 12 | True 13 | 14 | 15 | -------------------------------------------------------------------------------- /WIMCore/WimFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Security.Cryptography; 7 | using System.Text; 8 | using System.Xml.Linq; 9 | using WIMCore.Exceptions; 10 | 11 | namespace WIMCore 12 | { 13 | public class WimFile : IDisposable 14 | { 15 | private readonly FileStream _file; 16 | 17 | private WimHeader _header; 18 | 19 | private readonly WimImage[] _images; 20 | private IntegrityTable _integrityTable; 21 | private LookupTable _lookupTable; 22 | private readonly BinaryReader _reader; 23 | private readonly BinaryWriter _writer; 24 | private XDocument _xmlMetadata; 25 | 26 | public uint ImageCount => _header.ImageCount; 27 | public WimHeaderFlags Flags => _header.WimFlags; 28 | 29 | public WimFile(string path) 30 | { 31 | _file = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); 32 | _reader = new BinaryReader(_file, Encoding.Unicode, true); 33 | _writer = new BinaryWriter(_file, Encoding.Unicode, true); 34 | 35 | ReadWimHeader(); 36 | _images = new WimImage[_header.ImageCount]; 37 | 38 | ReadLookupTable(); 39 | } 40 | 41 | public void Dispose() 42 | { 43 | _writer.Flush(); 44 | 45 | _reader.Dispose(); 46 | _writer.Dispose(); 47 | _file.Dispose(); 48 | } 49 | 50 | public unsafe bool CheckIntegrity() 51 | { 52 | if (_header.IntegrityTable.OffsetInWim == 0) 53 | { 54 | throw new WimIntegrityException(WimIntegrityExceptionType.NoIntegrityData); 55 | } 56 | 57 | if (_integrityTable == null) 58 | { 59 | ReadIntegrityTable(); 60 | } 61 | 62 | bool verified = true; 63 | 64 | long chunkStart = 0; 65 | long chunkStartNum = chunkStart / _integrityTable.Header.ChunkSize; 66 | long chunkEnd = _header.XmlData.OffsetInWim - sizeof(WimHeader); 67 | long chunkEndNum = chunkEnd / _integrityTable.Header.ChunkSize; 68 | 69 | using (SHA1 sha = SHA1.Create()) 70 | { 71 | for (long i = chunkStartNum; i <= chunkEndNum; i++) 72 | { 73 | _file.Position = sizeof(WimHeader) + i * _integrityTable.Header.ChunkSize; 74 | 75 | int chunkSize = _file.Position + _integrityTable.Header.ChunkSize > _header.XmlData.OffsetInWim 76 | ? (int)(_header.XmlData.OffsetInWim - _file.Position) 77 | : (int)_integrityTable.Header.ChunkSize; 78 | 79 | byte[] data = _reader.ReadBytes(chunkSize); 80 | byte[] computedHash = sha.ComputeHash(data, 0, data.Length); 81 | 82 | for (int j = 0; j < computedHash.Length; j++) 83 | { 84 | verified &= computedHash[j] == _integrityTable.Hashes[i][j]; 85 | } 86 | } 87 | } 88 | 89 | return verified; 90 | } 91 | 92 | public void LoadImageMetadata() 93 | { 94 | for (int i = 0; i < ImageCount; i++) 95 | { 96 | LoadImageMetadata(i); 97 | } 98 | } 99 | 100 | private unsafe void ReadWimHeader() 101 | { 102 | if (_file.Length < sizeof(WimHeader)) 103 | { 104 | throw new WimInvalidException(WimInvalidExceptionType.InvalidSize); 105 | } 106 | 107 | _file.Position = 0; 108 | 109 | byte[] bHeader = _reader.ReadBytes(sizeof(WimHeader)); 110 | fixed (byte* pHeader = bHeader) 111 | { 112 | _header = Marshal.PtrToStructure((IntPtr)pHeader); 113 | } 114 | 115 | byte[] magic = 116 | { 117 | 0x4D, 118 | 0x53, 119 | 0x57, 120 | 0x49, 121 | 0x4D, 122 | 0, 123 | 0, 124 | 0 125 | }; 126 | 127 | bool valid = true; 128 | fixed (byte* magicFile = _header.Magic) 129 | { 130 | for (int i = 0; i < magic.Length; i++) 131 | { 132 | valid &= magic[i] == magicFile[i]; 133 | } 134 | } 135 | 136 | if (!valid) 137 | { 138 | throw new WimInvalidException(WimInvalidExceptionType.InvalidMagic); 139 | } 140 | } 141 | 142 | private unsafe void ReadLookupTable() 143 | { 144 | _file.Position = _header.LookupTable.OffsetInWim; 145 | ulong entries = _header.LookupTable.OriginalSize / (ulong)sizeof(LookupEntry); 146 | 147 | var entryArray = new LookupEntry[entries]; 148 | for (ulong i = 0; i < entries; i++) 149 | { 150 | byte[] bEntry = _reader.ReadBytes(sizeof(LookupEntry)); 151 | fixed (byte* pEntry = bEntry) 152 | { 153 | entryArray[i] = Marshal.PtrToStructure((IntPtr)pEntry); 154 | } 155 | } 156 | 157 | _lookupTable = new LookupTable(entryArray); 158 | } 159 | 160 | private unsafe void ReadIntegrityTable() 161 | { 162 | _file.Position = _header.IntegrityTable.OffsetInWim; 163 | 164 | byte[] bTable = _reader.ReadBytes(sizeof(IntegrityTableHeader)); 165 | IntegrityTableHeader itHeader; 166 | fixed (byte* pTable = bTable) 167 | { 168 | itHeader = Marshal.PtrToStructure((IntPtr)pTable); 169 | } 170 | 171 | var bbHashes = new byte[itHeader.TableRowCount][]; 172 | for (int i = 0; i < bbHashes.Length; i++) 173 | { 174 | bbHashes[i] = _reader.ReadBytes(20); 175 | } 176 | 177 | _integrityTable = new IntegrityTable(itHeader, bbHashes); 178 | } 179 | 180 | private unsafe void LoadImageMetadata(int imageIndex) 181 | { 182 | if (_lookupTable == null) 183 | { 184 | ReadLookupTable(); 185 | } 186 | 187 | if (imageIndex >= _header.ImageCount) 188 | { 189 | throw new ArgumentOutOfRangeException(nameof(imageIndex)); 190 | } 191 | 192 | LookupEntry metadataEntry = _lookupTable.Entries.Where(l => (l.Flags & ResourceHeaderFlags.Metadata) == ResourceHeaderFlags.Metadata).OrderBy(l => l.OffsetInWim).Skip(imageIndex).First(); 193 | 194 | _file.Position = metadataEntry.OffsetInWim; 195 | 196 | byte[] bTable = _reader.ReadBytes(sizeof(SecurityTableHeader)); 197 | SecurityTableHeader stHeader; 198 | fixed (byte* pTable = bTable) 199 | { 200 | stHeader = Marshal.PtrToStructure((IntPtr)pTable); 201 | } 202 | 203 | var sdLengths = new ulong[stHeader.EntryCount]; 204 | for (int i = 0; i < sdLengths.Length; i++) 205 | { 206 | sdLengths[i] = _reader.ReadUInt64(); 207 | } 208 | 209 | var sdDescriptors = new byte[stHeader.EntryCount][]; 210 | for (int i = 0; i < sdLengths.Length; i++) 211 | { 212 | sdDescriptors[i] = _reader.ReadBytes((int)sdLengths[i]); 213 | } 214 | 215 | SecurityTable st = new SecurityTable(stHeader, sdDescriptors); 216 | 217 | var dirEntries = new List(); 218 | while (_file.Position < metadataEntry.OffsetInWim + (long)metadataEntry.SizeInWim) 219 | { 220 | long startPosition = _file.Position; 221 | byte[] bdEntry = _reader.ReadBytes(sizeof(DirectoryEntry)); 222 | DirectoryEntry dEntry; 223 | fixed (byte* pdEntry = bdEntry) 224 | { 225 | dEntry = Marshal.PtrToStructure((IntPtr)pdEntry); 226 | } 227 | 228 | string name = Encoding.Unicode.GetString(_reader.ReadBytes(dEntry.FileNameLength)); 229 | 230 | var altStreams = new Dictionary(dEntry.Streams); 231 | for (int i = 0; i < dEntry.Streams; i++) 232 | { 233 | byte[] bsEntry = _reader.ReadBytes(sizeof(StreamEntry)); 234 | StreamEntry sEntry; 235 | fixed (byte* psEntry = bsEntry) 236 | { 237 | sEntry = Marshal.PtrToStructure((IntPtr)psEntry); 238 | } 239 | 240 | string sName = Encoding.Unicode.GetString(_reader.ReadBytes(sEntry.StreamNameLength)); 241 | 242 | altStreams.Add(sName, sEntry); 243 | } 244 | 245 | dirEntries.Add(new DirectoryTableEntry(name, dEntry, altStreams)); 246 | 247 | // TODO: Transveral logic 248 | } 249 | 250 | _images[imageIndex] = new WimImage(st, dirEntries.ToArray()); 251 | } 252 | 253 | private void ReadXmlMetadata() 254 | { 255 | _file.Position = _header.XmlData.OffsetInWim; 256 | 257 | byte[] bXml = _reader.ReadBytes((int)_header.XmlData.SizeInWim); 258 | using (MemoryStream mStr = new MemoryStream(bXml)) 259 | { 260 | _xmlMetadata = XDocument.Load(mStr); 261 | } 262 | } 263 | } 264 | } -------------------------------------------------------------------------------- /WIMCore/WimHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace WIMCore 5 | { 6 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 7 | public unsafe struct WimHeader 8 | { 9 | public fixed byte Magic [8]; 10 | public uint HeaderSize; 11 | public uint WimVersion; 12 | public WimHeaderFlags WimFlags; 13 | public uint ChunkSize; 14 | public Guid WimGuid; 15 | public ushort PartNumber; 16 | public ushort TotalParts; 17 | public uint ImageCount; 18 | public ResourceHeader LookupTable; 19 | public ResourceHeader XmlData; 20 | public ResourceHeader BootMetadata; 21 | public uint BootIndex; 22 | public ResourceHeader IntegrityTable; 23 | public fixed byte Unused [60]; 24 | } 25 | } -------------------------------------------------------------------------------- /WIMCore/WimHeaderFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WIMCore 4 | { 5 | [Flags] 6 | public enum WimHeaderFlags : uint 7 | { 8 | None = 0, 9 | Reserved = 1, 10 | Compressed = 2, 11 | ReadOnly = 4, 12 | Spanned = 8, 13 | ResourcesOnly = 0x10, 14 | MetadataOnly = 0x20, 15 | WriteInProgress = 0x40, 16 | ReparsePointFixup = 0x80, 17 | 18 | CompressReserved = 0x10000, 19 | CompressXpress = 0x20000, 20 | CompressLzx = 0x40000, 21 | CompressLzms = 0x80000, 22 | 23 | CompressXpress2 = 0x200000 24 | } 25 | } -------------------------------------------------------------------------------- /WIMCore/WimImage.cs: -------------------------------------------------------------------------------- 1 | namespace WIMCore 2 | { 3 | public class WimImage 4 | { 5 | private DirectoryTableEntry[] _directoryTable; 6 | private SecurityTable _securityTable; 7 | 8 | public WimImage(SecurityTable securityTable, DirectoryTableEntry[] directoryTable) 9 | { 10 | _securityTable = securityTable; 11 | _directoryTable = directoryTable; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace CryptoKeySite 4 | { 5 | public class FilterConfig 6 | { 7 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 8 | { 9 | filters.Add(new HandleErrorAttribute()); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/App_Start/MongoConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | 3 | namespace CryptoKeySite 4 | { 5 | internal static class MongoConfig 6 | { 7 | public static string Database { get; } 8 | public static string Host { get; } 9 | public static int Port { get; } 10 | 11 | static MongoConfig() 12 | { 13 | Host = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["data:MongoHost"]) 14 | ? ConfigurationManager.AppSettings["data:MongoHost"] 15 | : "localhost"; 16 | 17 | int port; 18 | bool success = int.TryParse(ConfigurationManager.AppSettings["data:MongoPort"], out port); 19 | if (!success) 20 | { 21 | port = 27017; // mongo default port 22 | } 23 | Port = port; 24 | 25 | Database = !string.IsNullOrEmpty(ConfigurationManager.AppSettings["data:MongoDB"]) 26 | ? ConfigurationManager.AppSettings["data:MongoDB"] 27 | : "MongoAuth"; 28 | } 29 | 30 | public static void SetupIndexes() 31 | { 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using System.Web.Routing; 3 | 4 | namespace CryptoKeySite 5 | { 6 | public class RouteConfig 7 | { 8 | public static void RegisterRoutes(RouteCollection routes) 9 | { 10 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 11 | 12 | routes.MapMvcAttributeRoutes(); 13 | routes.AppendTrailingSlash = true; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Controllers/WebController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using System.Web; 7 | using System.Web.Mvc; 8 | using System.Web.Security; 9 | using System.Xml.Linq; 10 | using CryptoKeySite.Models; 11 | 12 | namespace CryptoKeySite.Controllers 13 | { 14 | public class WebController : Controller 15 | { 16 | [Route("~/")] 17 | public async Task Index() 18 | { 19 | var ckr = new MongoRepository(); 20 | return View(await ckr.SelectDescending(ck => ck.FirstBuild)); 21 | } 22 | 23 | [Route("~/xml/")] 24 | public async Task XmlFeed() 25 | { 26 | var ckr = new MongoRepository(); 27 | List results = await ckr.SelectDescending(ck => ck.FirstBuild); 28 | 29 | Response.ContentType = "text/xml"; 30 | XDocument xdoc = new XDocument(new XElement("keys", 31 | from r in results 32 | select new XElement("key", new XAttribute("build", r.FirstBuild), new XAttribute("value", r.KeyBase64)))); 33 | 34 | xdoc.Save(Response.OutputStream); 35 | 36 | return new EmptyResult(); 37 | } 38 | 39 | [Route("~/add/")] 40 | [Authorize] 41 | public ActionResult Add() => View(); 42 | 43 | [Route("~/add/")] 44 | [Authorize] 45 | [HttpPost] 46 | public async Task Add(CryptoKey ck) 47 | { 48 | if (ModelState.IsValid) 49 | { 50 | ck.Id = Guid.NewGuid(); 51 | var ckr = new MongoRepository(); 52 | await ckr.Insert(ck); 53 | 54 | return RedirectToAction(nameof(Index)); 55 | } 56 | 57 | return View(ck); 58 | } 59 | 60 | [Route("~/delete/{id}/")] 61 | [Authorize] 62 | public async Task Delete(Guid id) 63 | { 64 | var ckr = new MongoRepository(); 65 | await ckr.DeleteById(id); 66 | 67 | return RedirectToAction(nameof(Index)); 68 | } 69 | 70 | [Route("~/logout/")] 71 | public ActionResult Logout() 72 | { 73 | FormsAuthentication.SignOut(); 74 | return RedirectToAction(nameof(Index)); 75 | } 76 | 77 | [Route("~/login/")] 78 | public ActionResult Login() => View(); 79 | 80 | [Route("~/login/")] 81 | [HttpPost] 82 | public ActionResult Login(LoginViewModel lvm) 83 | { 84 | if (ModelState.IsValid) 85 | { 86 | bool authSuccess = Membership.ValidateUser(lvm.Username, lvm.Password); 87 | 88 | if (authSuccess) 89 | { 90 | int expiryLength = lvm.RememberMe 91 | ? 129600 92 | : 60; 93 | 94 | FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(lvm.Username, true, expiryLength); 95 | string encryptedTicket = FormsAuthentication.Encrypt(ticket); 96 | 97 | HttpCookie cookieTicket = new HttpCookie(FormsAuthentication.FormsCookieName) 98 | { 99 | Value = encryptedTicket, 100 | Expires = DateTime.Now.AddMinutes(expiryLength), 101 | Path = FormsAuthentication.FormsCookiePath 102 | }; 103 | Response.Cookies.Add(cookieTicket); 104 | 105 | string returnUrl = string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]) 106 | ? "~/" 107 | : Request.QueryString["ReturnUrl"]; 108 | 109 | return Redirect(returnUrl); 110 | } 111 | } 112 | 113 | return View(lvm); 114 | } 115 | 116 | [Route("~/register/")] 117 | public ActionResult Register() 118 | { 119 | if (!bool.Parse(ConfigurationManager.AppSettings["EnableRegistrations"])) 120 | { 121 | return RedirectToAction(nameof(Index)); 122 | } 123 | return View(); 124 | } 125 | 126 | [Route("~/register/")] 127 | [HttpPost] 128 | public ActionResult Register(RegisterViewModel rvm) 129 | { 130 | if (!bool.Parse(ConfigurationManager.AppSettings["EnableRegistrations"])) 131 | { 132 | return RedirectToAction(nameof(Index)); 133 | } 134 | 135 | if (ModelState.IsValid) 136 | { 137 | MembershipCreateStatus status; 138 | MembershipUser mu = Membership.CreateUser(rvm.Username, rvm.Password, rvm.Username, "?", "!", true, out status); 139 | 140 | if (status == MembershipCreateStatus.Success) 141 | { 142 | mu.IsApproved = true; 143 | Membership.UpdateUser(mu); 144 | return RedirectToAction(nameof(Index)); 145 | } 146 | } 147 | 148 | return View(rvm); 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/CryptoKeySite.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Debug 9 | AnyCPU 10 | 11 | 12 | 2.0 13 | {B9C5EADE-631F-46A4-96B6-E5D3BA494F4B} 14 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 15 | Library 16 | Properties 17 | CryptoKeySite 18 | CryptoKeySite 19 | v4.6.2 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 2.1 30 | 31 | 32 | true 33 | full 34 | false 35 | bin\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | pdbonly 42 | true 43 | bin\ 44 | TRACE 45 | prompt 46 | 4 47 | gulpfile.js;package.json;packages.config 48 | 49 | 50 | 51 | ..\packages\Microsoft.ApplicationInsights.Agent.Intercept.2.0.1\lib\net45\Microsoft.AI.Agent.Intercept.dll 52 | True 53 | 54 | 55 | ..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.1.0\lib\net45\Microsoft.AI.DependencyCollector.dll 56 | True 57 | 58 | 59 | ..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.1.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll 60 | True 61 | 62 | 63 | ..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.1.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll 64 | True 65 | 66 | 67 | ..\packages\Microsoft.ApplicationInsights.Web.2.1.0\lib\net45\Microsoft.AI.Web.dll 68 | True 69 | 70 | 71 | ..\packages\Microsoft.ApplicationInsights.WindowsServer.2.1.0\lib\net45\Microsoft.AI.WindowsServer.dll 72 | True 73 | 74 | 75 | ..\packages\Microsoft.ApplicationInsights.2.1.0\lib\net46\Microsoft.ApplicationInsights.dll 76 | True 77 | 78 | 79 | ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll 80 | True 81 | 82 | 83 | 84 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 85 | True 86 | 87 | 88 | ..\..\BuildFeed\Authentication\MongoAuth\bin\Release\MongoAuth.dll 89 | 90 | 91 | ..\packages\MongoDB.Bson.2.2.4\lib\net45\MongoDB.Bson.dll 92 | True 93 | 94 | 95 | ..\packages\MongoDB.Driver.2.2.4\lib\net45\MongoDB.Driver.dll 96 | True 97 | 98 | 99 | ..\packages\MongoDB.Driver.Core.2.2.4\lib\net45\MongoDB.Driver.Core.dll 100 | True 101 | 102 | 103 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 104 | True 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll 116 | True 117 | 118 | 119 | ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll 120 | True 121 | 122 | 123 | ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll 124 | True 125 | 126 | 127 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll 128 | True 129 | 130 | 131 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll 132 | True 133 | 134 | 135 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll 136 | True 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | PreserveNewest 152 | 153 | 154 | default.scss 155 | 156 | 157 | default.css 158 | 159 | 160 | default.ts 161 | 162 | 163 | default.js 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | compilerconfig.json 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | Web.config 184 | 185 | 186 | Web.config 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | Global.asax 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 10.0 215 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | True 226 | True 227 | 50101 228 | / 229 | http://localhost:50101/ 230 | False 231 | False 232 | 233 | 234 | False 235 | 236 | 237 | 238 | 239 | 240 | 241 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 242 | 243 | 244 | 245 | 246 | 253 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="CryptoKeySite.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | 5 | namespace CryptoKeySite 6 | { 7 | public class MvcApplication : HttpApplication 8 | { 9 | protected void Application_Start() 10 | { 11 | AreaRegistration.RegisterAllAreas(); 12 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 13 | RouteConfig.RegisterRoutes(RouteTable.Routes); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Models/CryptoKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.Security.Cryptography; 4 | 5 | namespace CryptoKeySite.Models 6 | { 7 | public class CryptoKey : IModelWithId 8 | { 9 | [Display(Name = "First Build")] 10 | public int FirstBuild { get; set; } 11 | 12 | public byte[] Key { get; set; } 13 | 14 | [Display(Name = "Key")] 15 | public string KeyBase64 16 | { 17 | get { return Convert.ToBase64String(Key ?? Array.Empty()); } 18 | set { Key = Convert.FromBase64String(value); } 19 | } 20 | 21 | [Display(Name = "Exchange Algorithm")] 22 | public string KeyExchangeAlgorithm 23 | { 24 | get 25 | { 26 | using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) 27 | { 28 | rsa.ImportCspBlob(Key); 29 | return rsa.KeyExchangeAlgorithm; 30 | } 31 | } 32 | } 33 | 34 | [Display(Name = "Key Size")] 35 | public int KeySize 36 | { 37 | get 38 | { 39 | using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) 40 | { 41 | rsa.ImportCspBlob(Key); 42 | return rsa.KeySize; 43 | } 44 | } 45 | } 46 | 47 | public Guid Id { get; set; } 48 | } 49 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Models/IModelWithId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CryptoKeySite.Models 4 | { 5 | public interface IModelWithId 6 | { 7 | Guid Id { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Models/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace CryptoKeySite.Models 4 | { 5 | public class LoginViewModel 6 | { 7 | [Display(Name = "Email Address")] 8 | [DataType(DataType.EmailAddress)] 9 | [Required(ErrorMessage = "Please enter an email address.")] 10 | [EmailAddress(ErrorMessage = "Please enter a valid email address.")] 11 | public string Username { get; set; } 12 | 13 | [DataType(DataType.Password)] 14 | [Required(ErrorMessage = "Please enter a password.")] 15 | public string Password { get; set; } 16 | 17 | [Display(Name = "Remember me")] 18 | public bool RememberMe { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Models/MongoRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | using MongoDB.Bson; 6 | using MongoDB.Driver; 7 | 8 | namespace CryptoKeySite.Models 9 | { 10 | public class MongoRepository 11 | where T : IModelWithId 12 | { 13 | private readonly IMongoCollection _collection; 14 | 15 | public MongoRepository() 16 | { 17 | MongoClient dbClient = new MongoClient(new MongoClientSettings 18 | { 19 | Server = new MongoServerAddress(MongoConfig.Host, MongoConfig.Port) 20 | }); 21 | 22 | IMongoDatabase database = dbClient.GetDatabase(MongoConfig.Database); 23 | 24 | _collection = database.GetCollection(typeof(T).Name); 25 | } 26 | 27 | public async Task> Select() => await _collection.Find(new BsonDocument()).ToListAsync(); 28 | 29 | public async Task> SelectAscending(Expression> field) => await _collection.Find(new BsonDocument()).Sort(Builders.Sort.Ascending(field)).ToListAsync(); 30 | 31 | public async Task> SelectDescending(Expression> field) => await _collection.Find(new BsonDocument()).Sort(Builders.Sort.Descending(field)).ToListAsync(); 32 | 33 | public async Task SelectById(Guid id) => await _collection.Find(Builders.Filter.Eq(b => b.Id, id)).SingleOrDefaultAsync(); 34 | 35 | public async Task Insert(T item) 36 | { 37 | await _collection.InsertOneAsync(item); 38 | } 39 | 40 | public async Task DeleteById(Guid id) 41 | { 42 | await _collection.DeleteOneAsync(Builders.Filter.Eq(b => b.Id, id)); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Models/RegisterViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace CryptoKeySite.Models 4 | { 5 | public class RegisterViewModel 6 | { 7 | [Display(Name = "Email Address")] 8 | [DataType(DataType.EmailAddress)] 9 | [Required(ErrorMessage = "Please enter an email address.")] 10 | [EmailAddress(ErrorMessage = "Please enter a valid email address.")] 11 | public string Username { get; set; } 12 | 13 | [DataType(DataType.Password)] 14 | [Required(ErrorMessage = "Please enter a password.")] 15 | public string Password { get; set; } 16 | 17 | [Display(Name = "Confirm")] 18 | [DataType(DataType.Password)] 19 | [Compare(nameof(Password), ErrorMessage = "The passwords do not match.")] 20 | [Required(ErrorMessage = "Please enter a password.")] 21 | public string ConfirmPassword { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CryptoKeySite")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CryptoKeySite")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b9c5eade-631f-46a4-96b6-e5d3ba494f4b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model HandleErrorInfo 2 | @{ 3 | Layout = null; 4 | } 5 | 6 | 7 | 8 | 9 | 10 | Error 11 | 12 | 13 |
14 |

Error.

15 |

An error occurred while processing your request.

16 |
17 | 18 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using CryptoKeySite.Controllers 2 | 3 | 4 | 5 | 6 | 7 | @ViewBag.Title | CryptoKey Database 8 | 9 | 10 | 11 | 12 |
13 |
14 |

15 | CryptoKey Database 16 |

17 |
18 |
19 | @RenderBody() 20 |
21 |
22 |

23 | © @DateTime.Now.Year, Thomas Hounsell
24 | @if (User.Identity.IsAuthenticated) 25 | { 26 | Logout 27 | } 28 | else 29 | { 30 | Login 31 | } 32 |

33 |
34 |
35 | 36 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/Web/Add.cshtml: -------------------------------------------------------------------------------- 1 | @model CryptoKeySite.Models.CryptoKey 2 | 3 | @{ 4 | ViewBag.Title = "Add a CryptoKey"; 5 | } 6 | 7 |

Add a CryptoKey

8 | 9 | @using (Html.BeginForm()) 10 | { 11 | @Html.AntiForgeryToken() 12 | 13 |
14 | @Html.LabelFor(model => model.FirstBuild) 15 | @Html.TextBoxFor(model => model.FirstBuild, new 16 | { 17 | htmlAttributes = new 18 | { 19 | type = "number" 20 | } 21 | }) 22 | @Html.ValidationMessageFor(model => model.FirstBuild, "", new 23 | { 24 | @class = "text-danger" 25 | }) 26 |
27 | 28 |
29 | @Html.LabelFor(model => model.KeyBase64) 30 | @Html.TextAreaFor(model => model.KeyBase64) 31 | @Html.ValidationMessageFor(model => model.KeyBase64, "", new 32 | { 33 | @class = "text-danger" 34 | }) 35 |
36 | 37 | 38 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/Web/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using CryptoKeySite.Controllers 2 | @using CryptoKeySite.Models 3 | @model IEnumerable 4 | 5 | @{ 6 | ViewBag.Title = "Windows 10 | ESD Decryption"; 7 | } 8 | 9 |

10 | @if (User.Identity.IsAuthenticated) 11 | { 12 |  Add a key 13 | } 14 |  XML Feed 15 |

16 |

ESD Decryption Keys

17 | 18 | 19 | 20 | 23 | 26 | 29 | 32 | @if (User.Identity.IsAuthenticated) 33 | { 34 | 35 | } 36 | 37 | 38 | 39 | @foreach (CryptoKey item in Model) 40 | { 41 | 42 | 45 | 50 | 53 | 56 | @if (User.Identity.IsAuthenticated) 57 | { 58 | 66 | } 67 | 68 | } 69 | 70 |
21 | @Html.DisplayNameFor(model => model.FirstBuild) 22 | 24 | @Html.DisplayNameFor(model => model.KeyBase64) 25 | 27 | @Html.DisplayNameFor(model => model.KeyExchangeAlgorithm) 28 | 30 | @Html.DisplayNameFor(model => model.KeySize) 31 |
43 | @Html.DisplayFor(modelItem => item.FirstBuild) 44 | 46 |
47 | @Html.DisplayFor(modelItem => item.KeyBase64) 48 |
49 |
51 | @Html.DisplayFor(modelItem => item.KeyExchangeAlgorithm) 52 | 54 | @Html.DisplayFor(modelItem => item.KeySize) 55 | 59 | 63 | 64 | 65 |
71 | 72 |

Frequently asked questions

73 |

74 | What is an ESD?
75 | An ESD is a partially-encrypted Windows Installation image. Microsoft use these images to distribute a complete Windows setup over Windows Update. 76 |

77 |

78 | How do you decrypt an ESD?
79 | You can use the DecryptESD program, which uses the XML feed provided by this site to update its local store of crypto keys. 80 |

81 | 82 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/Web/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model CryptoKeySite.Models.LoginViewModel 2 | 3 | @{ 4 | ViewBag.Title = "Login"; 5 | } 6 | 7 | @using (Html.BeginForm()) 8 | { 9 | @Html.AntiForgeryToken() 10 | 11 |
12 | @Html.LabelFor(model => model.Username) 13 | @Html.EditorFor(model => model.Username) 14 | @Html.ValidationMessageFor(model => model.Username, "", new 15 | { 16 | @class = "text-error" 17 | }) 18 |
19 | 20 |
21 | @Html.LabelFor(model => model.Password) 22 | @Html.EditorFor(model => model.Password) 23 | @Html.ValidationMessageFor(model => model.Password, "", new 24 | { 25 | @class = "text-error" 26 | }) 27 |
28 | 29 |
30 | @Html.EditorFor(model => model.RememberMe) 31 | @Html.LabelFor(model => model.RememberMe) 32 | @Html.ValidationMessageFor(model => model.RememberMe, "", new 33 | { 34 | @class = "text-error" 35 | }) 36 |
37 | 38 | 39 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/Web/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model CryptoKeySite.Models.RegisterViewModel 2 | 3 | @{ 4 | ViewBag.Title = "Login"; 5 | } 6 | 7 | @using (Html.BeginForm()) 8 | { 9 | @Html.AntiForgeryToken() 10 | 11 |
12 | @Html.LabelFor(model => model.Username) 13 | @Html.EditorFor(model => model.Username) 14 | @Html.ValidationMessageFor(model => model.Username, "", new 15 | { 16 | @class = "text-error" 17 | }) 18 |
19 | 20 |
21 | @Html.LabelFor(model => model.Password) 22 | @Html.EditorFor(model => model.Password) 23 | @Html.ValidationMessageFor(model => model.Password, "", new 24 | { 25 | @class = "text-error" 26 | }) 27 |
28 | 29 |
30 | @Html.LabelFor(model => model.ConfirmPassword) 31 | @Html.EditorFor(model => model.ConfirmPassword) 32 | @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new 33 | { 34 | @class = "text-error" 35 | }) 36 |
37 | 38 | 39 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/Views/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/bundleconfig.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "outputFileName": "res/ts/default.min.js", 4 | "inputFiles": [ 5 | "res/ts/default.js" 6 | ] 7 | }, 8 | { 9 | "outputFileName": "res/scss/default.min.css", 10 | "inputFiles": [ 11 | "res/scss/default.css" 12 | ] 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/compilerconfig.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "outputFile": "res/scss/default.css", 4 | "inputFile": "res/scss/default.scss" 5 | } 6 | ] -------------------------------------------------------------------------------- /Website/CryptoKeySite/compilerconfig.json.defaults: -------------------------------------------------------------------------------- 1 | { 2 | "compilers": { 3 | "less": { 4 | "autoPrefix": "", 5 | "cssComb": "none", 6 | "ieCompat": true, 7 | "strictMath": false, 8 | "strictUnits": false, 9 | "relativeUrls": true, 10 | "rootPath": "", 11 | "sourceMapRoot": "", 12 | "sourceMapBasePath": "", 13 | "sourceMap": false 14 | }, 15 | "sass": { 16 | "includePath": "", 17 | "indentType": "space", 18 | "indentWidth": 2, 19 | "outputStyle": "nested", 20 | "Precision": 5, 21 | "relativeUrls": true, 22 | "sourceMapRoot": "", 23 | "sourceMap": false 24 | }, 25 | "stylus": { 26 | "sourceMap": false 27 | }, 28 | "babel": { 29 | "sourceMap": false 30 | }, 31 | "coffeescript": { 32 | "bare": false, 33 | "runtimeMode": "node", 34 | "sourceMap": false 35 | } 36 | }, 37 | "minifiers": { 38 | "css": { 39 | "enabled": true, 40 | "termSemicolons": true, 41 | "gzip": false 42 | }, 43 | "javascript": { 44 | "enabled": true, 45 | "termSemicolons": true, 46 | "gzip": false 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Website/CryptoKeySite/gulpfile.js: -------------------------------------------------------------------------------- 1 | /// 2 | var gulp = require('gulp'); 3 | var sass = require('gulp-sass'); 4 | 5 | gulp.task('sass-compile', 6 | function() { 7 | gulp.src('./res/scss/default.scss') 8 | .pipe(sass()) 9 | .pipe(gulp.dest('./res/scss/')); 10 | }); 11 | 12 | gulp.task('watch-sass', 13 | function() { 14 | gulp.watch('./res/scss/*.scss', ['sass-compile']); 15 | }); -------------------------------------------------------------------------------- /Website/CryptoKeySite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "crypto-key-site", 3 | "version": "1.0.0", 4 | "description": "A website that tracks known Crypto Keys", 5 | 6 | "devDependencies": { 7 | "gulp": "3.9.1", 8 | "gulp-sass": "2.3.2" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/res/scss/default.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | font-size: 10pt; 4 | margin: 0; 5 | background: #eee; 6 | color: #333; } 7 | 8 | * { 9 | -moz-box-sizing: border-box; 10 | -webkit-box-sizing: border-box; 11 | box-sizing: border-box; } 12 | 13 | header > h1 > a { 14 | color: #333; 15 | text-decoration: none; } 16 | 17 | .container { 18 | margin: 0 auto; 19 | width: 960px; 20 | max-width: 85%; } 21 | .container > footer { 22 | font-size: 0.8em; } 23 | 24 | .btn-add, 25 | .btn-info { 26 | display: inline-block; 27 | color: #fff; 28 | text-decoration: none; 29 | line-height: 1em; 30 | padding: 6px 10px; 31 | -moz-border-radius: 4px; 32 | -webkit-border-radius: 4px; 33 | border-radius: 4px; } 34 | 35 | .btn-add { 36 | background: #080; 37 | border: 1px solid #0c0; } 38 | 39 | .btn-info { 40 | background: #008; 41 | border: 1px solid #00c; } 42 | 43 | .table-listing { 44 | width: 100%; 45 | line-height: 1.5em; 46 | border-collapse: collapse; 47 | table-layout: fixed; } 48 | .table-listing th, 49 | .table-listing td { 50 | border: 1px solid #ccc; 51 | padding: 6px 11px; 52 | vertical-align: top; 53 | text-align: center; } 54 | .table-listing th > .break, 55 | .table-listing td > .break { 56 | -ms-word-wrap: break-word; 57 | word-wrap: break-word; 58 | height: 1.5em; 59 | overflow: hidden; 60 | -ms-text-overflow: ellipsis; 61 | -o-text-overflow: ellipsis; 62 | text-overflow: ellipsis; 63 | white-space: nowrap; } 64 | .table-listing th:nth-child(1), 65 | .table-listing td:nth-child(1) { 66 | width: 7em; } 67 | .table-listing th:nth-child(2), 68 | .table-listing td:nth-child(2) { 69 | text-align: left; } 70 | .table-listing th:nth-child(3), 71 | .table-listing td:nth-child(3) { 72 | width: 12em; } 73 | .table-listing th:nth-child(4), 74 | .table-listing td:nth-child(4) { 75 | width: 6em; } 76 | .table-listing th:nth-child(5), 77 | .table-listing td:nth-child(5) { 78 | width: 4em; } 79 | .table-listing a.table-listing-delete { 80 | color: #fff; 81 | background: #800; 82 | display: inline-block; 83 | line-height: 1em; 84 | padding: 2px 5px 4px; 85 | -moz-border-radius: 4px; 86 | -webkit-border-radius: 4px; 87 | border-radius: 4px; 88 | border: 1px solid #c00; } 89 | 90 | .form-group { 91 | margin-bottom: 1em; } 92 | .form-group input, .form-group textarea { 93 | display: block; } 94 | .form-group label, .form-group input[type=checkbox] { 95 | display: inline-block; 96 | margin-bottom: 4px; 97 | vertical-align: middle; } 98 | 99 | input[type=text], input[type=email], input[type=password], textarea { 100 | width: 100%; 101 | max-width: 400px; 102 | -moz-box-sizing: border-box; 103 | -webkit-box-sizing: border-box; 104 | box-sizing: border-box; 105 | border: 1px solid; 106 | padding: 0.33333em 0.5em; 107 | -moz-border-radius: 2px; 108 | -webkit-border-radius: 2px; 109 | border-radius: 2px; 110 | line-height: 1em; } 111 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/res/scss/default.min.css: -------------------------------------------------------------------------------- 1 | body{font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;font-size:10pt;margin:0;background:#eee;color:#333}*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}header>h1>a{color:#333;text-decoration:none}.container{margin:0 auto;width:960px;max-width:85%}.container>footer{font-size:.8em}.btn-add,.btn-info{display:inline-block;color:#fff;text-decoration:none;line-height:1em;padding:6px 10px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.btn-add{background:#080;border:1px solid #0c0}.btn-info{background:#008;border:1px solid #00c}.table-listing{width:100%;line-height:1.5em;border-collapse:collapse;table-layout:fixed}.table-listing th,.table-listing td{border:1px solid #ccc;padding:6px 11px;vertical-align:top;text-align:center}.table-listing th>.break,.table-listing td>.break{-ms-word-wrap:break-word;word-wrap:break-word;height:1.5em;overflow:hidden;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.table-listing th:nth-child(1),.table-listing td:nth-child(1){width:7em}.table-listing th:nth-child(2),.table-listing td:nth-child(2){text-align:left}.table-listing th:nth-child(3),.table-listing td:nth-child(3){width:12em}.table-listing th:nth-child(4),.table-listing td:nth-child(4){width:6em}.table-listing th:nth-child(5),.table-listing td:nth-child(5){width:4em}.table-listing a.table-listing-delete{color:#fff;background:#800;display:inline-block;line-height:1em;padding:2px 5px 4px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;border:1px solid #c00}.form-group{margin-bottom:1em}.form-group input,.form-group textarea{display:block}.form-group label,.form-group input[type=checkbox]{display:inline-block;margin-bottom:4px;vertical-align:middle}input[type=text],input[type=email],input[type=password],textarea{width:100%;max-width:400px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid;padding:.33333em .5em;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;line-height:1em} -------------------------------------------------------------------------------- /Website/CryptoKeySite/res/scss/default.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | font-size: 10pt; 4 | margin: 0; 5 | background: #eee; 6 | color: #333; 7 | } 8 | 9 | * { 10 | -moz-box-sizing: border-box; 11 | -webkit-box-sizing: border-box; 12 | box-sizing: border-box; 13 | } 14 | 15 | header > h1 > a { 16 | color: #333; 17 | text-decoration: none; 18 | } 19 | 20 | .container { 21 | margin: 0 auto; 22 | width: 960px; 23 | max-width: 85%; 24 | 25 | > footer { 26 | font-size: 0.8em; 27 | } 28 | } 29 | 30 | .btn-add, 31 | .btn-info { 32 | display: inline-block; 33 | color: #fff; 34 | text-decoration: none; 35 | line-height: 1em; 36 | padding: 6px 10px; 37 | -moz-border-radius: 4px; 38 | -webkit-border-radius: 4px; 39 | border-radius: 4px; 40 | } 41 | 42 | .btn-add { 43 | background: #080; 44 | border: 1px solid #0c0; 45 | } 46 | 47 | .btn-info { 48 | background: #008; 49 | border: 1px solid #00c; 50 | } 51 | 52 | .table-listing { 53 | width: 100%; 54 | line-height: 1.5em; 55 | border-collapse: collapse; 56 | table-layout: fixed; 57 | 58 | th, 59 | td { 60 | border: 1px solid #ccc; 61 | padding: 6px 11px; 62 | vertical-align: top; 63 | text-align: center; 64 | 65 | > .break { 66 | -ms-word-wrap: break-word; 67 | word-wrap: break-word; 68 | height: 1.5em; 69 | overflow: hidden; 70 | -ms-text-overflow: ellipsis; 71 | -o-text-overflow: ellipsis; 72 | text-overflow: ellipsis; 73 | white-space: nowrap; 74 | } 75 | } 76 | 77 | th:nth-child(1), 78 | td:nth-child(1) { 79 | width: 7em; 80 | } 81 | 82 | th:nth-child(2), 83 | td:nth-child(2) { 84 | text-align: left; 85 | } 86 | 87 | th:nth-child(3), 88 | td:nth-child(3) { 89 | width: 12em; 90 | } 91 | 92 | th:nth-child(4), 93 | td:nth-child(4) { 94 | width: 6em; 95 | } 96 | 97 | th:nth-child(5), 98 | td:nth-child(5) { 99 | width: 4em; 100 | } 101 | 102 | a.table-listing-delete { 103 | color: #fff; 104 | background: #800; 105 | display: inline-block; 106 | line-height: 1em; 107 | padding: 2px 5px 4px; 108 | -moz-border-radius: 4px; 109 | -webkit-border-radius: 4px; 110 | border-radius: 4px; 111 | border: 1px solid #c00; 112 | } 113 | } 114 | 115 | .form-group { 116 | margin-bottom: 1em; 117 | 118 | input, textarea { 119 | display: block; 120 | } 121 | 122 | label, input[type=checkbox] { 123 | display: inline-block; 124 | margin-bottom: 4px; 125 | vertical-align: middle; 126 | } 127 | } 128 | 129 | input[type=text], input[type=email], input[type=password], textarea { 130 | width: 100%; 131 | max-width: 400px; 132 | -moz-box-sizing: border-box; 133 | -webkit-box-sizing: border-box; 134 | box-sizing: border-box; 135 | border: 1px solid; 136 | padding: 0.33333em 0.5em; 137 | -moz-border-radius: 2px; 138 | -webkit-border-radius: 2px; 139 | border-radius: 2px; 140 | line-height: 1em; 141 | } 142 | -------------------------------------------------------------------------------- /Website/CryptoKeySite/res/ts/default.js: -------------------------------------------------------------------------------- 1 | var KeySite; 2 | (function (KeySite) { 3 | function copyKey(mev) { 4 | var key = this; 5 | var range = document.createRange(); 6 | range.selectNode(key); 7 | var selection = window.getSelection(); 8 | selection.removeAllRanges(); 9 | selection.addRange(range); 10 | document.execCommand("copy"); 11 | } 12 | KeySite.copyKey = copyKey; 13 | })(KeySite || (KeySite = {})); 14 | var keys = document.getElementsByClassName("break"); 15 | for (var i = 0; i < keys.length; i++) { 16 | keys[i].addEventListener("click", KeySite.copyKey); 17 | } 18 | ; 19 | //# sourceMappingURL=default.js.map -------------------------------------------------------------------------------- /Website/CryptoKeySite/res/ts/default.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"default.js","sourceRoot":"","sources":["default.ts"],"names":[],"mappings":"AAAA,IAAO,OAAO,CAcb;AAdD,WAAO,OAAO;IAEV,iBAAwB,GAAe;QAEnC,IAAM,GAAG,GAAG,IAAsB,CAAC;QAEnC,IAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACtB,IAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;QACxC,SAAS,CAAC,eAAe,EAAE,CAAC;QAC5B,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE1B,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAXe,eAAO,UAWtB,CAAA;AACL,CAAC,EAdM,OAAO,KAAP,OAAO,QAcb;AAED,IAAM,IAAI,GAAG,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACtD,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EACpC,CAAC;IACG,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;AACvD,CAAC;AAAA,CAAC"} -------------------------------------------------------------------------------- /Website/CryptoKeySite/res/ts/default.min.js: -------------------------------------------------------------------------------- 1 | var KeySite,Keys,i;for(function(n){function t(){var i=this,t=document.createRange(),n;t.selectNode(i);n=window.getSelection();n.removeAllRanges();n.addRange(t);document.execCommand("copy")}n.CopyKey=t}(KeySite||(KeySite={})),Keys=document.getElementsByClassName("break"),i=0;i