Cannot navigate to https pages using self-signed certificate

I have a problem which I ‘sort of’ understand – but I don’t know why the issue occurs only on remote computers.

I have Netzero mobile broadband, it’s a USB stick in my laptop. Provides me WIFI whereever I go (just like a cell phone works anywhere). Naturally this means I have an identity (a numeric IP address) when using it.

Today, in this same laptop, I open a browser and surf to the IP address. I would imagine that, to the browser, it looks just like any standard remote IP address – or does it know that it’s the local machine?

Maybe it does know the difference because I get a different result when I surf to that IP address from a remote machine (for instance a machine using Comcast WIFI).

The reason I’m surfing to my own IP address is to navigate to my web page. I’m a noobie testing my first web application.

I’m getting two different results regarding SSL/https pages (it’s a self-signed certificate).
- On the local machine, the browsers give me a warning about the certificate but then allow me to go to the page.
- On remote machines, the browsers (both phones and laptops) simply won’t let me goto the page – and I don’t even get a certificate warning, I get the following errors instead, which say nothing about certificates.
- Error 67 on phones suggesting no wifi-connectivity (which is just not true as I can surf the web), PLUS the errors below:
- "This page is not available".
- 404 error
- Timeout error
First, I don’t know why the remote machines are behaving differently than the local machine. Second, does anyone know a way that I can override this restraint? Because at this point I want to test my website on phones and I don’t see how to navigate to it. 

Maybe I should buy a ‘real’ certificate? I haven’t done so because this website is just a learning exercise, I will probably never publish it.

Let me stress that the problem occurs only on https pages. If I remove the [requireHttps] attribute and then use http instead of https, I can see the web pages. But I really need a better solution than that. 

From what I gather, the recommended solution seems to be using openSSL to create a root certificate, thereby establishing myself as my own certificate authority.  Then use the root certificate to create/stamp a user-level SSL certificate.

However, the SSL certificate will be pinned to a particular IP address/domain. I want to be able to access:

(1) the local domain (local host)

(2) Multiple Ip addresses.

I’m currently taking a look at the SubjectAltName extensions – maybe that will help. 

Any additional advice would be appreciated.

I used the XCA tool at sourceforge because it has an easy GUI screen to create a multi-domain CA certificate. I added both ‘localhost’ and my current Netzero IP address. On my local machine it worked fine – both addresses lit up the Chrome address bar in
green. I installed the CA cert on the remote machines as well (Trusted Cert Authorities store). But I still can’t get remote machines to honor it, can’t surf to https pages.

Suggestions, anyone? I’ve been working on this for two days pulling my hair out.

Hi jal2,

Thanks for your post. Based on your description, it seems that the remote machine cannot access the target IP address. Could you do a simple test? Put a static HTML page on your web server and test if you can access it from remote machine with HTTP protocol.

If we exclude the network issue, then I hope following articles are useful to you.

How to Set Up SSL on IIS 7:

http://www.iis.net/learn/manage/configuring-security/how-to-set-up-ssl-on-iis

How to trust the IIS Express Self-Signed Certificate:

http://blogs.iis.net/robert_mcmurray/archive/2013/11/15/how-to-trust-the-iis-express-self-signed-certificate.aspx

Best regards

for the remote machines to honor the cert will depend on the program (browsers) and os. the certificates signing authority needs to be added to the root authority. for IE and chrome on windows, you can install the authority cert (from the self signer authority)
to the root. see additional instructions for firefox. for a phone/tablet, you will need a rooted device to update its cert authority. 

if you have an azure account or any other hosted provider, you can create a proxy service to your laptop. the azure site with a valid cert will call your laptop using web client, where you can override the cert authentication.

Not sure what you mean by root authority. I thought I was doing that already. Let me clarify. On the local machine, as I stated, I had some success with a single (self-signed) CA cert installed both in Trusted Authorities AND in IIS (but still no remote
success).

So I decided to produce a second cert – a user cert signed by the CA cert. I tried two different tools (and with both tools I started from scratch allowing the tool to create a new CA cert to start with, then a user-cert).

(1) OpenSSL command line using a configuration file. I guess I can post that file here.

(2) XCA graphical tool

The XCA graphical tool is nice because it shows the results onscreen after the process. It shows that the user-cert is in fact signed by the CA cert. All the info is in green suggesting things went smoothly.

Next I installed the CA cert (using mmc) into Trusted Root Authorities (after deleting any previous self-signed certs I had tried). And then I tried to installed the user-cert into IIS, but IIS is throwing an error about chaining – but I don’t see how I
could have made a chaining error given that the XCA GUI tool is pretty straightforward. The error says,"One or more intermediate certificates in the certificate chain are missing.  To resolve this issue, make sure that all of the intermediate certificates
are installed."

Furthermore, if my chaining was wrong, why is it that Firefox accepts it? I had to install the certs into firefox separately, but at least they work on the local machine, though not remotely. 

Here’s my openSSL configuration file, in case anyone wants to see it. Sorry about the copious notes/comments I added as I’ve been struggling to figure this stuff out.

####################################################################
[ ca ]
default_ca    = CA_default        # The default-ca section provides default values for a CA certificate.
####################################################################
[ CA_default ]
# This section sets up for signing a CSR, that is, for using an existing CA cert to

# generate a user-cert from a CSR.
# With filepaths, I don’t know whether the paths supplied on the command-line at runtime override
# the paths specified below, so what I did was, as much as possible, removed any lines below with
# path values as to rely on the command-line values.
                # With paths, just mentally reverse the forward slashes to backslashes to understand them.

dir        = .        #  ‘dir’ is a variable name used to specify the base directory. A period means

                #’use current dir’. Can’t use abslute paths but can use a relataive one like ./Certs if you
                # created ca Certs directory. I begin with cd C:Certs to make Certs my current dir.
                # Going forward we can refer to this dir using ‘$dir’ as a variable name.

                # Apparently you need to have a directory for certificate revocations in

                #    case you decide to revoke any of those you spawned.  I think the browsers
                # check this list of revocations periodically.
certs        = $dir        # dir where the issued certs are kept
crl_dir        = $dir        # dir where the certificate revocations are kept
# Mandatory. You must create the serial.txt textfile beforehand – and it must have

# the current serialNO in hex – just create an empty file containing the string 01
serial        = $dir/serial.txt    
database    = $dir/index.txt    # Mandatory. Database index file. Just create an empty textfle called index.txt.

unique_subject    = no            # Set to ‘no’ to allow creation of several ctificates with same subject.
new_certs_dir    = $dir        # default place for new certs.
private_key = $dir/caKey.key
HOME = .            # Period to indicae current directory. Used below with a rand function to create a random FILENAME (I think).

RANDFILE       = HOME/.rnd  # private random number file
#crlnumber    = $dir/crlnumber    # Ditto of the current CRL number (huh?)
                    # must be commented out to create a V1 CRL
#crl        = $dir/crl.pem             # The current CRL (Certificate Revocation List)

x509_extensions    = usr_cert        # The extentions to add to the cert

# He says ‘Comment out the following two lines for the "traditional" (and highly broken) format.’
# But I have no idea how these two lines work.
name_opt     = ca_default        # Subject Name options   huh? Points back to this section?    
cert_opt     = ca_default        # Certificate field options  huh?

# Extensions to add to a CRL (Certificate Revocation List). Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to create a V1 CRL.
# crlnumber must also be commented out to create a V1 CRL.
# crl_extensions    = crl_ext

default_days    = 3650            # how long to certify for
default_crl_days= 30            # how long before the next CRL Certificate Revocation List is published.

default_md    = sha256                #md means message digest/hash         
preserve    = no            # keep passed Distinguished Name ordering  huh?
email_in_dn                = no
# In the ‘policy’ section, type ‘match’ on any field where you want to require the user-cert

# to match the CA-cert on this value. Type ‘optional’ if you don’t mind a mismatch.
# I decided to mark them all ‘optional’ below.
# For the CA policy
policy        = policy_match
####################################################################
[ policy_match ]
#edit this section as desired
countryName        = optional
stateOrProvinceName    = optional
organizationName    = optional
organizationalUnitName    = optional
commonName        = supplied
emailAddress        = optional    #email values can always be left blank.

# For the ‘anything’ policy  (huh?)
# At this point in time, you must list all acceptable ‘object’
# types.
[ policy_anything ]
countryName        = optional
stateOrProvinceName    = optional
localityName        = optional
organizationName    = optional
organizationalUnitName    = optional
commonName        = supplied
emailAddress        = optional

####################################################################
[ req ]
# A REQUEST for a signed certificate is the opposite of a self-signed certificate. Yet even
# a  self-signed certificate uses this whole [req] section to specify/configure the cert’s values.

# Values set here are apparently final, as opposed to the ‘suggested’ values (i.e. the default

# values) supplied in the ca_default section.
days                 = 3650   #Honored on self-signed certs, ignored on certificate requests
default_bits        = 2048
default_md                = sha256                # message digest algorithm
default_keyfile     = privatekey.pem
distinguished_name    = req_distinguished_name
attributes        = req_attributes
x509_extensions    = v3_ca    # The extensions to add to the self signed cert
string_mask = utf8only # This sets a mask for permitted string types.
###################################################################
[ req_distinguished_name ]
# Again, a REQUEST for a cert is the opposite of a self-signed cert. This section

# is used regardless of which of these two opposites is currently being executed.
#The user wlll be promted for the following values (you can supply some defaults though).
# by adding a suffix _default as shown below. If you supply ALL the default values, the
# child certs will look just like the CA cert (can’t tell them apart).
# These field-names are often given as one-letter or two letter abbreviations such as
#  CN=www.google.de, O=Google Inc, OU=Google Authority, L=Mountain View, S=California, C=US
# where ‘CN’ is for Common Name, ‘O’ for organization, ‘OU’ for
#Organizational unit L for Locale/city, S for State, and C for country.
countryName            = Country Name (2 letter code)  #<—- user will see this prompt
countryName_default        = US      # <—— default value supplied
countryName_min            = 2
countryName_max            = 2
stateOrProvinceName        = State or Province Name (full name) #<—- user will see this prompt
stateOrProvinceName_default    = FL     # <—— default value supplied
localityName            = Locality Name (eg, city) #<—- user will see this prompt
localityName_default    = Jacksonille    # <—— defeult value supplied
# Below the ’0.’ prefix means the primary Organization name. You
# can specify a secondary Organization name using the ’1.’ prefix (optional).
0.organizationName        = Organization Name (eg, company)
#1.organizationName        = Secondary Organization Name (eg, company)
# In fact you can use the above numbering scheme to supply multiple values of anything such as email:
#     0.emailAddress=moe@curlyshouse
#     1.emailAddress=moe@larryshouse
#    2.emailAddress=moe@moeshouse
organizationalUnitName        = Organizational Unit Name (eg, section)
commonName            = Common Name (e.g. server FQDN or YOUR name)
commonName_default = 50.13.194.60
commonName_max            = 64
emailAddress            = Email Address
emailAddress_max        = 64
[ req_attributes ]
challengePassword        = A challenge password
challengePassword_min        = 4
challengePassword_max        = 20
##################################################################
[ usr_cert ]
# These extensions are added when an existing CA signs a request.
# Hence these values will be applied only to user-certs
basicConstraints=CA:FALSE    #Do not omit this line.
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign,cRLSign
extendedKeyUsage = serverAuth, clientAuth    # EKU is short for exended key usage.

# The following will be displayed in Netscape’s comment listbox.
nsComment            = "OpenSSL Generated Certificate"
# The subjectKeyIdentifier specifies "how to identify the public key being certified. The
# only valid value is ‘hash’ "
subjectKeyIdentifier=hash
# The authorityKeyIdentifier "specifies how to identify the public key being used to

# verify the signature on this certificate" (huh?) where ‘keyid’ means to use the parent

# certificate’s hash/subjectKeyId and ‘issuer’ means ‘use the parent cert’s issuer and serialNO’,

authorityKeyIdentifier=keyid,issuer     #
# Type here your subjectAltName values. If you have multiple IPs, then
# list the first one as IP.1, then IP.2 – and do the same with DNS names if you have several.
# Actually I don’t think you have to number them as IP.1 and IP.2, you could just do "IP:" for each.

# Same with DNS – you could "DNS:" for each one.
subjectAltName = DNS.1:localhost, IP.1:50.13.194.60
# ‘Issuer’ is mentioned above but I don’t know where this value gets suppplied.
# The purpose of issuer Alternative Name, if used, is to provide additional identifying
# names such as the issuer’s email address, his IP address, a DNS name, or a URL.  This field
# doesn’tseem to be proving useful. Uses the same format as subjectAltName although I don’t think
# you should ever include email addresses.
# issuerAltName=issuer:copy
####################################################################
[ v3_ca ]
# This section is a fullfillment of the above line ‘x509_extensions    = v3_ca’
# It covers the extensions for a typical CA. Thus it does not apply to user-certs, for
# example note the value below ‘CA:true’ which can only refer to a CA-cert, not a user-cert.

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true,pathlen:1    #Avoid using the word critical as it throws some software.

keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign,cRLSign
extendedKeyUsage = serverAuth, clientAuth
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
subjectAltName = DNS.1:localhost, IP.1:50.13.194.60

####################################################################
[ crl_ext ]
# CRL extensions. Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always

Update: At least with the CA cert produced by the XCA tool,  I did eliminate the IIS error message – I guess it turns out that these two stores are not co-equal:

Trusted Root (user)

Trusted Root (local computer)

I was using the first one, but using the 2nd one seems to have fixed the IIS error, I don’t know why. So now it’s working again on the local machine.

But I still can’t connect to https pages from  a remote machine.

Leave a Reply