private static CertificateChainWithPrivateKey ReadOrCreateCA(string certPath) { var directory = Path.GetDirectoryName(certPath) ?? Environment.CurrentDirectory; var baseName = Path.GetFileNameWithoutExtension(certPath); var keyPath = Path.Combine(directory, baseName + ".key"); if (!File.Exists(keyPath) || !File.Exists(certPath)) { Console.WriteLine($"[info] missing CA certificate or key, creating a new one: " + $"{Path.Combine(directory, baseName + ".pem")}"); var certWithKey = CertificateCreator.CreateCACertificate(); SavePemCertificate(certWithKey, directory, baseName, false); return(certWithKey); } using var keyFileReader = File.OpenText(keyPath); var pemReader = new PemReader(keyFileReader); var keyParameters = (RsaPrivateCrtKeyParameters)pemReader.ReadObject(); using var certFileStream = File.OpenRead(certPath); var certificates = new X509CertificateParser().ReadCertificates( certFileStream).OfType <X509Certificate>().ToArray(); return(new CertificateChainWithPrivateKey(certificates, keyParameters)); }
private static int Main(string[] args) { var flags = new[] { "int", "client", "ecdsa", "chain", "pfx", "h", "?", "help" }; var parsedArgs = CommandLineHelper.ParseArgs(flags, args); if (parsedArgs.ContainsKey("h") || parsedArgs.ContainsKey("help") || parsedArgs.ContainsKey("?")) { ShowInfoAndUsage(); return(1); } try { if (!parsedArgs.TryGetValue("ca", out var rootCertPath)) { rootCertPath = Path.Combine(Environment.CurrentDirectory, "concertoCA.pem"); } parsedArgs.TryGetValue("crl", out var crlUri); if (parsedArgs.ContainsKey("int")) { // we are creating intermediate certificate if (!parsedArgs.TryGetValue(string.Empty, out var certName)) { throw new CommandLineArgumentException( "-int: you need to provide a name for the intermediate certificate"); } var rootCertWithKey = ReadOrCreateCA(rootCertPath); SavePemCertificate( CertificateCreator.CreateCACertificate(rootCertWithKey, certName, crlUri), Environment.CurrentDirectory, certName, parsedArgs.ContainsKey("chain")); } else { parsedArgs.TryGetValue(string.Empty, out var hostsStr); var hosts = (hostsStr ?? "").Split(new[] { ',', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (hosts.Length == 0) { throw new CommandLineArgumentException( "you need to provide at least one name to create a certificate"); } var rootCertWithKey = ReadOrCreateCA(rootCertPath); var cert = CertificateCreator.CreateCertificate(rootCertWithKey, hosts, parsedArgs.ContainsKey("client"), parsedArgs.ContainsKey("ecdsa"), crlUri); if (parsedArgs.ContainsKey("pfx")) { SavePkcs12Certificate(cert, Environment.CurrentDirectory, SanitizeFileName(hosts[0]), parsedArgs.ContainsKey("chain")); } else { SavePemCertificate(cert, Environment.CurrentDirectory, SanitizeFileName(hosts[0]), parsedArgs.ContainsKey("chain")); } } return(0); } catch (Exception ex) when(ex is CommandLineArgumentException || ex is ConcertoUsageException) { Console.WriteLine($"[error] {ex.Message}"); Console.WriteLine($" {AppName.Name} -help to see usage info."); return(1); } catch (Exception ex) { Console.WriteLine($"[critical] {ex.Message}"); Console.WriteLine("Please report this error at https://github.com/lowleveldesign/concerto/issues, " + "providing the below details."); Console.WriteLine("=== Details ==="); Console.WriteLine(ex); Console.WriteLine(); Console.WriteLine($"Command line: {Environment.CommandLine}"); Console.WriteLine($"OS: {Environment.OSVersion}"); Console.WriteLine($"x64 (OS): {Environment.Is64BitOperatingSystem}"); Console.WriteLine($"x64 (Process): {Environment.Is64BitProcess}"); return(1); } }