0 votes
by (120 points)

Dear Sir or Madam,

I am trying to setup a test HTTPS Web server in a specific domain created in the local machine and with the DNS Server of the machine (everything is in a local network for testing).

The HTTP web server is working with the http://www.exampledomain.com

However, in HTTPS, there is a problem since it is not possible to work with https://www.exampledomain.com. The Certificate is included in the "Trusted Root Certification Authorities" store but the web browser gives an error:

NET::ERRCERTCOMMONNAMEINVALID
This server could not prove that it is www.exampledomain.com; its security certificate is from localhost. This may be caused by a misconfiguration or an attacker intercepting your connection.

Note: https://localhost is working fine.

I do not know if this is a limitation of the application due to that the certificate that is created is only valid for https://localhost and the application can only work with https://localhost.

I do not know if there is a way to include more Server URLs in the application or any way to overcome this problem.

Any comment is welcome.

Thanks.

Best regards,
Eduardo

1 Answer

0 votes
by (70.2k points)

The certificate used by the Rebex Tiny Web Server is specified using the serverCertificateFile key in the .config file.

To make the process easier for testing, the application generates a self-signed certificate if the specified certificate does not exist on the disk when the server is starting. The generated certificate is issued for localhost and the "Machine Name" (for example PC001) so the server can be accessed using https://localhost and https://PC001 without issues.

For other domain names you have to provide your own valid certificate.

You can generate/request the certificate using your favorite tool.


For programmers:
If you want to issue a self-signed certificate similar to one generated automatically (but for your custom domain), you can do it programmatically using Rebex.Common like this:

/// <summary>
/// Issues self signed certificate for server authentication.
/// </summary>
private void IssueSelfSignedCertificate(string domain, string filename, string password)
{
    // Prepare certificate info.
    var info = new CertificateInfo();

    // Specify certificate validity range.
    info.EffectiveDate = DateTime.Now.AddDays(-1);
    info.ExpirationDate = info.EffectiveDate.AddYears(10);

    // Specify certificate subject.
    info.Subject = new DistinguishedName(string.Format("CN={0}, OU=Rebex Tiny Web Server", domain));

    // Set alternative names.
    info.SetAlternativeHostnames(domain);

    // Specify certificate key usage for server certificate.
    info.Usage = KeyUses.DigitalSignature;

    // Specify certificate usage for server authentication.
    info.SetExtendedUsage(ExtendedUsageOids.ServerAuthentication);

    // Sets a unique serial number.
    info.SetSerialNumber(Guid.NewGuid().ToByteArray());

    // Use SHA-256 signature algorithm (or SHA-1 in legacy mode).
    info.SignatureHashAlgorithm = HashingAlgorithmId.SHA256;

    // Generate a 2048-bit RSA key for the certificate (or 512-bit in legacy mode).
    PrivateKeyInfo privateKey;
    using (var alg = new AsymmetricKeyAlgorithm())
    {
        alg.GenerateKey(AsymmetricKeyAlgorithmId.RSA, 2048);
        privateKey = alg.GetPrivateKey();
    }

    // Create the self-signed certificate.
    Certificate certificate = CertificateIssuer.Issue(info, privateKey);

    // Associate the private key with the certificate.
    certificate.Associate(privateKey);

    // Save generated certificate into a PFX file with supplied password.
    certificate.Save(filename, CertificateFormat.Pfx, password);
}

Security notice: If you generate your own self-signed certificate for this usecase, make sure it is issued with DigitalSignature key usage only and ServerAuthentication extended usage only - you don't want to issue general certificate authority.

...