using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.RegularExpressions; using QRBee.Core.Security; namespace QRBee.Api.Services { internal class SecurityService : SecurityServiceBase { public SecurityService(IPrivateKeyHandler privateKeyHandler) : base(privateKeyHandler) { } /// public override X509Certificate2 CreateCertificate(string subjectName, byte[] rsaPublicKey) { throw new ApplicationException("Client never issues certificates"); } /// /// Generate Client certificate request (i.e. without KeyCertSign usage extension) /// /// /// /// private static CertificateRequest CreateRequest(X500DistinguishedName distinguishedName, RSA rsa) { var request = new CertificateRequest( distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1 ); request.CertificateExtensions.Add( new X509KeyUsageExtension( X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, //| X509KeyUsageFlags.KeyCertSign, false)); // request.CertificateExtensions.Add( // new X509EnhancedKeyUsageExtension( // new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false)); return request; } private const string CertHeader = "-----BEGIN CERTIFICATE-----"; private const string CertFooter = "-----END CERTIFICATE-----"; /// public override X509Certificate2 Deserialize(string pemData) { var start = pemData.IndexOf(CertHeader); if (start == -1) throw new ApplicationException("Invalid certificate format"); start = start + CertHeader.Length; var end = pemData.IndexOf(CertFooter); if (end == -1) throw new ApplicationException("Invalid certificate format"); var base64 = pemData.Substring(start, end - start); // contains new lines, but it does not matter var data = Convert.FromBase64String(base64); return new X509Certificate2(data); } /// public override string Serialize(X509Certificate2 cert) { // https://stackoverflow.com/questions/43928064/export-private-public-keys-from-x509-certificate-to-pem var builder = new StringBuilder(); builder.AppendLine(CertHeader); builder.AppendLine(Convert.ToBase64String(cert.RawData, Base64FormattingOptions.InsertLineBreaks)); builder.AppendLine(CertFooter); return builder.ToString(); } } }