multiple subdomains into certificate capability

This commit is contained in:
root 2019-07-21 14:40:15 +02:00
parent ffccea8480
commit 95d2edca4b
4 changed files with 24 additions and 29 deletions

View File

@ -85,10 +85,10 @@ namespace ACMEv2
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
/// <param name="home"></param> /// <param name="home"></param>
public LetsEncryptClient(string url, string home) public LetsEncryptClient(string url, string home, string siteName)
{ {
_url = url ?? throw new ArgumentNullException(nameof(url)); _url = url ?? throw new ArgumentNullException(nameof(url));
var hash = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(url)); var hash = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(siteName));
_home = home ?? Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, _home = home ?? Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData,
Environment.SpecialFolderOption.Create); Environment.SpecialFolderOption.Create);
@ -349,10 +349,10 @@ namespace ACMEv2
/// </summary> /// </summary>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
public async Task<(X509Certificate2 Cert, RSA PrivateKey)> GetCertificate(CancellationToken token = default(CancellationToken)) public async Task<(X509Certificate2 Cert, RSA PrivateKey)> GetCertificate(string subject, CancellationToken token = default(CancellationToken))
{ {
var key = new RSACryptoServiceProvider(4096); var key = new RSACryptoServiceProvider(4096);
var csr = new CertificateRequest("CN=" + _currentOrder.Identifiers[0].Value, var csr = new CertificateRequest("CN=" + subject,
key, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); key, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var san = new SubjectAlternativeNameBuilder(); var san = new SubjectAlternativeNameBuilder();
@ -382,7 +382,7 @@ namespace ACMEv2
var cert = new X509Certificate2(Encoding.UTF8.GetBytes(pem)); var cert = new X509Certificate2(Encoding.UTF8.GetBytes(pem));
_cache.CachedCerts[_currentOrder.Identifiers[0].Value] = new CertificateCache _cache.CachedCerts[subject] = new CertificateCache
{ {
Cert = pem, Cert = pem,
Private = key.ExportCspBlob(true) Private = key.ExportCspBlob(true)
@ -503,10 +503,10 @@ namespace ACMEv2
/// <param name="hosts"></param> /// <param name="hosts"></param>
/// <param name="value"></param> /// <param name="value"></param>
/// <returns></returns> /// <returns></returns>
public bool TryGetCachedCertificate(string [] hosts, out CachedCertificateResult value) public bool TryGetCachedCertificate(string subject, out CachedCertificateResult value)
{ {
value = null; value = null;
if (_cache.CachedCerts.TryGetValue(hosts[0], out var cache) == false) if (_cache.CachedCerts.TryGetValue(subject, out var cache) == false)
{ {
return false; return false;
} }

View File

@ -31,12 +31,12 @@ namespace LetsEncrypt
try { try {
//define cache folder //define cache folder
string cache = Path.Combine(AppPath, "cache", customer.id, site.name); string cache = Path.Combine(AppPath, "cache", customer.id);
if(!Directory.Exists(cache)) { if(!Directory.Exists(cache)) {
Directory.CreateDirectory(cache); Directory.CreateDirectory(cache);
} }
LetsEncryptClient client = new LetsEncryptClient(settings.url, cache); LetsEncryptClient client = new LetsEncryptClient(settings.url, cache, site.name);
//1. Client initialization //1. Client initialization
Console.WriteLine("1. Client Initialization..."); Console.WriteLine("1. Client Initialization...");
@ -53,7 +53,7 @@ namespace LetsEncrypt
// if valid check if cert and key exists otherwise recreate // if valid check if cert and key exists otherwise recreate
// else continue with new certificate request // else continue with new certificate request
CachedCertificateResult certRes = new CachedCertificateResult(); CachedCertificateResult certRes = new CachedCertificateResult();
if (client.TryGetCachedCertificate(site.hosts, out certRes)) if (client.TryGetCachedCertificate(site.name, out certRes))
{ {
string cert = Path.Combine(ssl, site.name + ".crt"); string cert = Path.Combine(ssl, site.name + ".crt");
if(!File.Exists(cert)) if(!File.Exists(cert))
@ -68,11 +68,6 @@ namespace LetsEncrypt
Console.WriteLine("Certificate and Key exists and valid."); Console.WriteLine("Certificate and Key exists and valid.");
} }
else { else {
//check if folder for the site exists
if(!Directory.Exists(Path.Combine(settings.www, site.name))) {
throw new DirectoryNotFoundException(string.Format("Site {0} wasn't initialized", site.name));
}
//new nonce //new nonce
client.NewNonce().Wait(); client.NewNonce().Wait();
@ -89,8 +84,8 @@ namespace LetsEncrypt
//ensure to enable static file discovery on server in .well-known/acme-challenge //ensure to enable static file discovery on server in .well-known/acme-challenge
//and listen on 80 port //and listen on 80 port
//check acme directory of the web site //check acme directory
string acme = Path.Combine(settings.www, site.name, settings.acme); string acme = Path.Combine(settings.www, settings.acme);
if(!Directory.Exists(acme)) { if(!Directory.Exists(acme)) {
throw new DirectoryNotFoundException(string.Format("Directory {0} wasn't created", acme)); throw new DirectoryNotFoundException(string.Format("Directory {0} wasn't created", acme));
} }
@ -136,11 +131,11 @@ namespace LetsEncrypt
// Download new certificate // Download new certificate
Console.WriteLine("4. Download certificate..."); Console.WriteLine("4. Download certificate...");
client.GetCertificate().Wait(); client.GetCertificate(site.name).Wait();
// Write to filesystem // Write to filesystem
certRes = new CachedCertificateResult(); certRes = new CachedCertificateResult();
if (client.TryGetCachedCertificate(site.hosts, out certRes)) { if (client.TryGetCachedCertificate(site.name, out certRes)) {
string cert = Path.Combine(ssl, site.name + ".crt"); string cert = Path.Combine(ssl, site.name + ".crt");
File.WriteAllText(cert, certRes.Certificate); File.WriteAllText(cert, certRes.Certificate);

View File

@ -38,6 +38,7 @@ namespace LetsEncrypt
} }
public class Site { public class Site {
public string root { get; set; }
public string name { get; set; } public string name { get; set; }
public string [] hosts { get; set; } public string [] hosts { get; set; }
public string challenge { get; set; } public string challenge { get; set; }

View File

@ -22,15 +22,9 @@
"name": "maks-it.com", "name": "maks-it.com",
"hosts": [ "hosts": [
"maks-it.com", "maks-it.com",
"www.maks-it.com" "www.maks-it.com",
],
"challenge": "http-01"
},
{
"name": "api.maks-it.com",
"hosts": [
"api.maks-it.com", "api.maks-it.com",
"www.api.maks-it.com" "www.api.maks-it.com",
], ],
"challenge": "http-01" "challenge": "http-01"
} }
@ -45,14 +39,19 @@
"sites": [ "sites": [
{ {
"name": "nastyarey.com", "name": "nastyarey.com",
"hosts": [ "hosts": [
"nastyarey.com", "nastyarey.com",
"www.nastyarey.com" "www.nastyarey.com",
"it.nastyarey.com",
"www.it.nastyarey.com",
"ru.nastyarey.com",
"www.ru.nastyarey.com"
], ],
"challenge": "http-01" "challenge": "http-01"
} }
] ]
} }
] ]
} }