ECC on BadSSL (First Part)

This is two part story of incorporating elliptic curve cryptography in BadSSL.

In mid December 2016, I decided to start work on incorporating elliptic curve cryptography in BadSSL. Now before I started work on developing the source code, I needed to do a quick refresh on elliptic curve cryptography and the associated RFCs to check if the related curves I was planning to incorporate was acceptable, supported and recommended for future use, then after that, I was ready to start developing. The planned curves were both Prime256v1 (256-Bit) and Secp384r1 (384-Bit).

First of all, I went to BadSSL GitHub repository and forked a local copy of the source code and then I spend few hours getting myself acquainted with the code. After that, I started work in the certs/tool file on implementing a mechanism to generate the require EC keys. Now as BadSSL already used OpenSSL to generate others keys on the platform I thought it would be a good idea to use OpenSSL ecparam function so I didn't have to include any extra dependencies.

gen-ecckey)
   openssl ecparam \
   -out $OUT \
   -name $1 \
   -genkey
;;

Next, I opened the certs/MakeFile and implemented the following code which allows the creation of EC keys, certificate requests and the signing of the certificate requests by local SubCA.

$(O)/gen/key/subdomain-ecc256.key:
        ./tool gen-ecckey $@ $(D) prime256v1

Creates the require EC key.

$(O)/gen/csr/subdomain-ecc256.csr: src/conf/subdomain-ecc256.conf 
$(O)/gen/key/subdomain-ecc256.key
        ./tool gen-csr $@ $(D) $^

Creates certificate request ready for signing by the local SubCA.

$(O)/gen/crt/subdomain-ecc256.crt: src/conf/subdomain-ecc256.conf 
$(O)/gen/csr/subdomain-ecc256.csr $(O)/gen/key/ca-intermediate.key 
$(O)/gen/crt/ca-intermediate.crt
        ./tool sign $@ $(D) $(SIGN_LEAF_DEFAULTS) $^
 CHAINS_LOCAL_ONLY += $(O)/gen/chain/subdomain-ecc256.pem
 $(O)/gen/chain/subdomain-ecc256.pem: $(O)/gen/crt/subdomain-ecc256.crt 
 $(O)/gen/crt/ca-intermediate.crt
        ./tool chain $@ $(D) $^

Signs the certificate request and produces a functioning certificate.

$(O)/gen/key/subdomain-ecc384.key:
           ./tool gen-ecckey $@ $(D) secp384r1 
$(O)/gen/csr/subdomain-ecc384.csr: src/conf/subdomain-ecc384.conf 
$(O)/gen/key/subdomain-ecc384.key
   ./tool gen-csr $@ $(D) $^
$(O)/gen/crt/subdomain-ecc384.crt: src/conf/subdomain-ecc384.conf 
$(O)/gen/csr/subdomain-ecc384.csr $(O)/gen/key/ca-intermediate.key 
$(O)/gen/crt/ca-intermediate.crt
   ./tool sign $@ $(D) $(SIGN_LEAF_DEFAULTS) $^
CHAINS_LOCAL_ONLY += $(O)/gen/chain/subdomain-ecc384.pem
$(O)/gen/chain/subdomain-ecc384.pem: $(O)/gen/crt/subdomain-ecc384.crt 
$(O)/gen/crt/ca-intermediate.crt
   ./tool chain $@ $(D) $^

Once I got all the above implemented correctly, it was time to create the necessary configuration files.

  1. OpenSSL Request configuration file for both ECC-256 and ECC-384:

    [ req ]
    default_bits        = 2048
    distinguished_name  = req_distinguished_name
    encrypt_key         = no
    prompt              = no
    req_extensions      = req_v3_usr
    
    
    [ req_distinguished_name ]
    countryName         = US
    stateOrProvinceName = California
    localityName        = San Francisco
    organizationName    = BadSSL
    commonName          = ecc256.__DOMAIN__
    
    
    [ req_v3_usr ]
    basicConstraints = CA:FALSE
    subjectAltName = @alt_names
    
    
    [ alt_names ]    
    DNS.1 = ecc256.__DOMAIN__
    

    (ECC-256)

    [ req ]
    default_bits        = 2048
    distinguished_name  = req_distinguished_name
    encrypt_key         = no
    prompt              = no
    req_extensions      = req_v3_usr
    
    
    [ req_distinguished_name ]
    countryName         = US
    stateOrProvinceName = California
    localityName        = San Francisco
    organizationName    = BadSSL
    commonName          = ecc384.__DOMAIN__
    
    
    [ req_v3_usr ]
    basicConstraints = CA:FALSE
    subjectAltName = @alt_names
    
    
    [ alt_names ]    
    DNS.1 = ecc384.__DOMAIN__
    

    (ECC-384)

  2. Nginx server configuration file for both ECC-256 and ECC-384:

    ---
    ---
    server {
       listen 80;
       server_name ecc256.{{ site.domain }};
    
    
       return 301 https://$server_name$request_uri;
    }
    
    
    server {
       listen 443;
       server_name ecc256.{{ site.domain }};
    
    
       include {{ site.serving-path }}/nginx-includes/subdomain-ecc256.conf;
       include {{ site.serving-path }}/nginx-includes/tls-mozilla-intermediate.conf;
       include {{ site.serving-path }}/common/common.conf;
    
    
       root {{ site.serving-path }}/domains-local-only/cert/ecc256;
    }
    

    (ECC-256)

    ---
    ---
    server {
       listen 80;
       server_name ecc384.{{ site.domain }};
    
    
       return 301 https://$server_name$request_uri;
    }
    
    
    server {
       listen 443;
       server_name ecc384.{{ site.domain }};
    
    
       include {{ site.serving-path }}/nginx-includes/subdomain-ecc384.conf;
       include {{ site.serving-path }}/nginx-includes/tls-mozilla-intermediate.conf;
       include {{ site.serving-path }}/common/common.conf;
    
    
       root {{ site.serving-path }}/domains-local-only/cert/ecc384;
    }
    

    (ECC-384)

  3. Another nginx server configuration file for both ECC-256 and ECC-384:

    ---        
    ---
    
    
    ssl on;
    ssl_certificate {{ site.cert-path }}/subdomain-ecc256.pem;
    ssl_certificate_key /etc/keys/subdomain-ecc256.key;
    

    (ECC-256)

    ---        
    ---
    
    
    ssl on;
    ssl_certificate {{ site.cert-path }}/subdomain-ecc384.pem;
    ssl_certificate_key /etc/keys/subdomain-ecc384.key;
    

    (ECC-384)

After all the configuration files were created. I started work on the creation of index.html files needed for both ECC-256 and ECC-384 implementations.

---
subdomain: ecc256
layout: page
favicon: green
background: green
---

<div id="content">
   <h1 style="font-size: 12vw;">
   {{ page.subdomain }}.<br>{{ site.domain }}
   </h1>
</div>

<div id="footer">
  This site uses a 256 bit ECC (elliptic curve cryptography) certificate.
</div>

(ECC-256)

---
subdomain: ecc384
layout: page
favicon: green
background: green
---

<div id="content">
   <h1 style="font-size: 12vw;">
   {{ page.subdomain }}.<br>{{ site.domain }}
   </h1>
</div>

<div id="footer">
  This site uses a 384 bit ECC (elliptic curve cryptography) certificate.
</div>

(ECC-384)

Now I'm ready to test the code. So I created a server on Google Cloud Platform and uploaded the code onto the server and with custom domain I successfully tested the code.

Now its time to create a pull request on GitHub and get the code included into the official BadSSL source code. In the code review I did need to make few minor corrections but other than that the code was excellent.

This implementation was to include ECC in BadSSL for local use only. So in part two, I'm going to explain the process of getting the code working on BadSSL.com.

I would like to thank both Lucas Garron and April King for their help and time.

James Burton

Read more posts by this author.

Subscribe to James Burton

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!