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();
}
}
}