[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / tools / security / httpcfg.cs
blob8a7df877da98d79cffd2b4b32490376c0d9f3f47
1 //
2 // httpcfg.cs: manages certificates used by HttpListener
3 //
4 // Authors:
5 // Gonzalo Paniagua Javier <gonzalo@novell.com>
6 // Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
9 //
11 using System;
12 using System.IO;
13 using System.Reflection;
14 using System.Security.Cryptography;
15 using System.Security.Cryptography.X509Certificates;
16 using Mono.Security.Authenticode;
18 [assembly: AssemblyTitle ("Mono Certificate Management for HttpListener use")]
19 [assembly: AssemblyDescription ("Manage X.509 certificates to be used in HttpListener.")]
21 namespace Mono.Tools {
22 class HttpCfg {
23 enum Action {
24 None,
25 Add,
26 Delete,
27 List
30 static Action action;
31 static string pvkfile;
32 static string certfile;
33 static string p12file;
34 static string passwd;
35 static ushort port;
37 static void Help (bool exit)
39 Console.WriteLine ("Usage is:\n" +
40 "\thttpcfg -add -port NN [-cert CERT -pvk PVK] [-p12 P12 -pwd PASSWORD]\n" +
41 "\thttpcfg -del -port NN\n" +
42 "\thttpcfg -list");
43 if (exit)
44 Environment.Exit (1);
47 static void ProcessArguments (string [] args)
49 for (int i = 0; i < args.Length; i++){
50 string arg = args [i];
51 switch (arg){
52 case "-add":
53 if (action != Action.None) {
54 Console.Error.WriteLine ("error: conflicting options.");
55 Help (true);
57 action = Action.Add;
58 break;
59 case "-del":
60 case "-delete":
61 if (action != Action.None) {
62 Console.Error.WriteLine ("error: conflicting options.");
63 Help (true);
65 action = Action.Delete;
66 break;
67 case "-list":
68 if (action != Action.None) {
69 Console.Error.WriteLine ("error: conflicting options.");
70 Help (true);
72 action = Action.List;
73 break;
74 case "-port":
75 if (port != 0) {
76 Console.Error.WriteLine ("error: more than one port specified.");
77 Help (true);
80 try {
81 port = Convert.ToUInt16 (args [++i]);
82 } catch (IndexOutOfRangeException) {
83 Console.Error.WriteLine ("Error: no port specified.");
84 Help (true);
85 } catch {
86 Console.Error.WriteLine ("Error: invalid port.");
87 Help (true);
89 break;
91 case "-p12":
92 if (p12file != null) {
93 Console.Error.WriteLine ("error: more than one p12 file specified.");
94 Help (true);
97 if (pvkfile != null || certfile != null) {
98 Console.Error.WriteLine ("error: use either -p12 or -pvk and -cert.");
99 Help (true);
101 p12file = args [++i];
102 break;
104 case "-pvk":
105 if (pvkfile != null) {
106 Console.Error.WriteLine ("error: more than one PVK file specified.");
107 Help (true);
110 if (p12file != null) {
111 Console.Error.WriteLine ("error: use either -p12 or -pvk and -cert.");
112 Help (true);
115 pvkfile = args [++i];
116 break;
117 case "-cert":
118 if (certfile != null) {
119 Console.Error.WriteLine ("error: more than one CER file specified.");
120 Help (true);
123 if (p12file != null) {
124 Console.Error.WriteLine ("error: use either -p12 or -pvk and -cert.");
125 Help (true);
128 certfile = args [++i];
129 break;
131 case "-pwd":
132 if (passwd != null) {
133 Console.Error.WriteLine ("error: more than one password specified.");
134 Help (true);
136 passwd = args [++i];
137 break;
139 default:
140 Console.Error.WriteLine ("error: Unknown argument: {0}", arg);
141 Help (true);
142 break;
146 if (action == Action.None) {
147 Console.Error.WriteLine ("error: no action specified.");
148 Help (true);
151 if ((pvkfile != null && certfile == null) || (pvkfile == null && certfile != null)) {
152 Console.Error.WriteLine ("error: -cert and -pvk must be used.");
153 Help (true);
156 if (action != Action.List && port == 0) {
157 Console.Error.WriteLine ("error: -port is missing or bogus.");
158 Help (true);
161 if (action == Action.Delete && (pvkfile != null || certfile != null || p12file != null)) {
162 //if (action == Action.Delete && (pvkfile != null || certfile != null)) {
163 Console.Error.WriteLine ("error: -delete only expects a -port option.");
164 Help (true);
169 static void AddP12 (string path, string filename, string password, ushort port)
171 X509Certificate2 x509 = null;
172 try {
173 x509 = new X509Certificate2 (filename, password);
174 } catch (Exception e) {
175 Console.Error.WriteLine ("error loading certificate [{0}]", e.Message);
176 Help (true);
179 string target_cert = Path.Combine (path, String.Format ("{0}.cer", port));
180 if (File.Exists (target_cert)) {
181 Console.Error.WriteLine ("error: there is already a certificate for that port.");
182 Help (true);
184 string target_pvk = Path.Combine (path, String.Format ("{0}.pvk", port));
185 if (File.Exists (target_pvk)) {
186 Console.Error.WriteLine ("error: there is already a certificate for that port.");
187 Help (true);
190 using (Stream cer = File.OpenWrite (target_cert)) {
191 byte [] raw = x509.RawData;
192 cer.Write (raw, 0, raw.Length);
195 PrivateKey pvk = new PrivateKey();
196 pvk.RSA = x509.PrivateKey as RSA;
197 pvk.Save(target_pvk);
201 static void AddCertPvk (string path, string cert, string pvk, ushort port)
203 try {
204 X509Certificate2 x509 = new X509Certificate2 (cert);
205 var privateKey = PrivateKey.CreateFromFile (pvk).RSA;
206 x509 = x509.CopyWithPrivateKey ((RSA)privateKey);
207 } catch (Exception e) {
208 Console.Error.WriteLine ("error loading certificate or private key [{0}]", e.Message);
209 Help (true);
212 string target_cert = Path.Combine (path, String.Format ("{0}.cer", port));
213 if (File.Exists (target_cert)) {
214 Console.Error.WriteLine ("error: there is already a certificate for that port.");
215 Help (true);
217 string target_pvk = Path.Combine (path, String.Format ("{0}.pvk", port));
218 if (File.Exists (target_pvk)) {
219 Console.Error.WriteLine ("error: there is already a certificate for that port.");
220 Help (true);
222 File.Copy (cert, target_cert);
223 File.Copy (pvk, target_pvk);
226 static void Delete (string path, ushort port)
228 string pattern = String.Format ("{0}.*", port);
229 string [] files = Directory.GetFiles (path, pattern);
230 foreach (string f in files) {
231 try {
232 File.Delete (f);
233 } catch (Exception e) {
234 Console.Error.WriteLine ("error removing file {0} [{1}].", f, e.Message);
239 static void List (string path)
241 string [] files = Directory.GetFiles (path, "*");
242 foreach (string f in files) {
243 if (f.EndsWith (".cer")) {
244 X509Certificate2 x509 = new X509Certificate2 (f);
245 Console.WriteLine ("Port: {0} Thumbprint: {1}", Path.GetFileNameWithoutExtension (f), x509.Thumbprint);
250 static int Main (string[] args)
252 try {
253 ProcessArguments (args);
254 } catch (IndexOutOfRangeException) {
255 Console.Error.WriteLine ("error: missing argument.");
256 Help (true);
259 if (action == Action.None) {
260 Help (true);
263 string dirname = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
264 string path = Path.Combine (dirname, ".mono");
265 path = Path.Combine (path, "httplistener");
266 if (false == Directory.Exists (path)) {
267 try {
268 Directory.CreateDirectory (path);
269 } catch (Exception e) {
270 Console.Error.WriteLine ("error: creating directory {0} [{1}]", path, e.Message);
271 return 1;
275 switch (action) {
276 case Action.Add:
277 if (p12file != null)
278 AddP12 (path, p12file, passwd, port);
279 else
280 AddCertPvk (path, certfile, pvkfile, port);
281 break;
282 case Action.Delete:
283 Delete (path, port);
284 break;
285 case Action.List:
286 List (path);
287 break;
289 return 0;