123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net.Http.Json;
- using System.Runtime;
- using System.Runtime.ConstrainedExecution;
- using System.Security.Cryptography;
- using System.Security.Cryptography.X509Certificates;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace EVCB_OCPP.WSServer.Service
- {
- public class CertificateService
- {
- public CertificateService(
- ServerMessageService messageService,
- IConfiguration configuration,
- ILogger<CertificateService> logger)
- {
- _serverUrl = configuration["CertificateServerUrl"];
- _cpon = configuration["ChargingPointOperator"];
- this.messageService = messageService;
- this.logger = logger;
- }
- private readonly string _serverUrl;
- private readonly string _cpon;
- private readonly ServerMessageService messageService;
- private readonly ILogger<CertificateService> logger;
- public async Task SignCertificate(string chargeBoxId, string csr)
- {
- HttpClient client = new HttpClient();
- client.BaseAddress = new Uri(_serverUrl);
- var signResult = await client.PostAsJsonAsync("cert/csr", new { csr = csr });
- if (!signResult.IsSuccessStatusCode)
- {
- logger.LogWarning("{chargeBoxId} csr failed {csr}", chargeBoxId, csr);
- return;
- }
- var crt = await signResult.Content.ReadAsStringAsync();
- await messageService.SendCertificateSignedRequest(chargeBoxId, crt);
- client.Dispose();
- }
- public Task<int> CheckClientCertificate(string chargeboxId, X509Certificate2 cert)
- {
- return CheckClientCertificate(chargeboxId, cert.ExportCertificatePem());
- }
- public async Task<int> CheckClientCertificate(string chargeboxId, string certString)
- {
- var subject = GetCertificateSubject(certString);
- logger.LogInformation("{chargeboxId} with cert subject {subject}", chargeboxId, subject);
- if (string.IsNullOrEmpty(subject))
- {
- return -1;
- }
- var crtInfo = SubjectToDictionary(subject);
- if (crtInfo == null ||
- //!crtInfo.ContainsKey("O") ||
- //crtInfo["O"] != _cpon ||
- !crtInfo.ContainsKey("CN") ||
- crtInfo["CN"] != chargeboxId)
- {
- return -1;
- }
- int certServerResult = await CheckClientCertificateRca(certString);
- logger.LogInformation("{chargeboxId} with cert authenticate {subject}", chargeboxId, certServerResult);
- return certServerResult;
- }
- public async Task<int> CheckClientCertificateRca(string certString)
- {
- using HttpClient client = new HttpClient();
- client.BaseAddress = new Uri(_serverUrl);
- var result = await client.PutAsJsonAsync("cert/crt", new { crt = certString });
- if (!result.IsSuccessStatusCode)
- {
- return -1;
- }
- var resultContentString = await result.Content.ReadAsStringAsync();
- return Convert.ToInt32(resultContentString);
- }
- public Dictionary<string, string> SubjectToDictionary(string subject)
- {
- try
- {
- MatchCollection regexResult = Regex.Matches(subject, "([a-zA-Z]*)=([a-zA-Z0-9]*)");
- if (regexResult.Count == 0)
- {
- return null;
- }
- return regexResult.Where(x => x.Success == true && x.Groups.Count == 3).ToDictionary(x => x.Groups[1].Value, x => x.Groups[2].Value);
- }
- catch (Exception e)
- {
- logger.LogCritical(e.Message);
- logger.LogCritical(e.StackTrace);
- return null;
- }
- }
- public string GetCertificateSubject(string crt)
- {
- try
- {
- byte[] bytes = Encoding.ASCII.GetBytes(crt);
- var clientCertificate = new X509Certificate2(bytes);
- return clientCertificate.Subject;
- }
- catch
- {
- return null;
- }
- }
- public string GetCertificateRequestSubject(string csrString)
- {
- try
- {
- var csr = CertificateRequest.LoadSigningRequestPem(csrString, HashAlgorithmName.SHA512);
- var test = csr.SubjectName.Name;
- return test;
- }
- catch
- {
- return null;
- }
- }
- }
- }
|