Saturday, 24 January 2015

Linux SSL, Autosigned Certitifcates. Apache, C++ client and server.

 

Linux SSL Client Server communication

R-PI Preloaded SD Cards at https://www.redypis.org 

 

Motto: ambiguous = agile

Prerequisite: Linux system, openssl.

To ensure a secured communication between a server and client you need on both sides a certificate and and a private key. 

  • Both sides(client and server) would have their individual private keys (server.key) and (client.key)

  • Both sides (client and server) would have a certificate signed by a certificate authority. 

We can create the certificate authority, keys and certificates for both, client and server. The attached picture illustrate the location  of the certificates generated by the attached script. Also the picture shows how certificates are correlated with the CA. The openssl.cfg file which is used by the script is attached down the post.



 

#
# OpenSSL configuration file.
#

# Establish working directory.

dir                    = .

[ ca ]
default_ca                = CA_default

[ CA_default ]
serial                    = $dir/serial
database                = $dir/certindex.txt
new_certs_dir            = $dir/certs
certificate                = $dir/cacert.pem
private_key                = $dir/private/cakey.pem
default_days            = 740
default_md                = md5
preserve                = no
email_in_dn                = no
nameopt                    = default_ca
certopt                    = default_ca
policy                    = policy_match

[ policy_match ]
countryName                = match
stateOrProvinceName            = match
organizationName            = match
organizationalUnitName            = optional
commonName                = supplied
emailAddress                = optional

[ req ]
default_bits                = 2048            # Size of keys
default_keyfile                = key.pem        # name of generated keys
default_md                = md5                # message digest algorithm
string_mask                = nombstr        # permitted characters
distinguished_name            = req_distinguished_name
req_extensions                = v3_req

[ req_distinguished_name ]
# Variable name                Prompt string
#-------------------------      ----------------------------------
0.organizationName            = Organization Name (company)
organizationalUnitName            = Organizational Unit Name (department, division)
emailAddress                = Email Address
emailAddress_max            = 40
localityName                = Locality Name (city, district)
stateOrProvinceName            = State or Province Name (full name)
countryName                = Country Name (2 letter code)
countryName_min                = 2
countryName_max                = 2
commonName                = Common Name (hostname, IP, or your name)
commonName_max                = 64

# Default values for the above, for consistency and less typing.
# Variable name                Value
#------------------------      ------------------------------
0.organizationName_default        = coinscode
localityName_default            = Richmond Hill
stateOrProvinceName_default        = ON
countryName_default            = CA

[ v3_ca ]
basicConstraints            = CA:TRUE
subjectKeyIdentifier            = hash
authorityKeyIdentifier            = keyid:always,issuer:always

[ v3_req ]
basicConstraints            = CA:FALSE
subjectKeyIdentifier            = hash

[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
 

Script: Creates

  • RCA - root CA key and certificate
  • SRV -  key and certificate
  • CLI - key and certificate

Each time the script deletes the output folder, otherwise you will get DB error. To create new keys with same CA comment the CA generation and adapt the script to use the existent CA.

#!/bin/bash

rm -rfv OUT
mkdir OUT

cp openssl.cnf OUT/
pushd OUT

touch certindex.txt        # index file.
mkdir newcerts         # new certs dir
echo 22 > serial
echo 00 > crlnumber   
mkdir private  
mkdir csr
mkdir certs

EBITS=2048

function crea_key()
{
    NAME=$1
    openssl genrsa -des3 -passout pass:12345678 -out ./private/$NAME $EBITS            # CA.key
    openssl rsa -passin pass:12345678 -in ./private/$NAME -out ./private/$NAME        # remove passout from CA.key
}

function crea_csr()
{
    KEY=$1
    CSR=$2
    SUBJ=$3
    openssl req -config ./openssl.cnf -new -subj "$SUBJ" -key ./private/$KEY -out ./csr/$CSR                                      
}

function crea_cert()
{
    RKEY=$1  
    RCRT=$2
    CSR=$3
    CERT=$4
    openssl ca -batch -config ./openssl.cnf -days 740 -in csr/$CSR -out certs/$CERT -keyfile private/$RKEY -cert certs/$RCRT -policy policy_anything # SRV certificate
}

function crea_cert_autosign()
{
    SUBJ=$1  
    PKEY=$2
    CERT=$3
    openssl req -config ./openssl.cnf -new -x509 -subj "$SUBJ" -days 740 -key ./private/$PKEY -out ./certs/$CERT # self sign CA certificate
}


echo "=====================================CA-----------------------------------"
##  CA key and self signed certificate   private/CA.key  certs/CA.crt
crea_key "RCA.key"
crea_cert_autosign "/C=CA/L=rhill/O=coinscode CA/CN=screen.webhop" "RCA.key" "RCA.crt"


echo "=====================================SRV----------------------------------"
## SRV SSL certificate
crea_key "SRV.key"
crea_csr "SRV.key"  "SRV.csr" "/C=CA/L=rhill/O=coinscode/CN=screen.webhop"
echo "------------------------------------------------------------------------"
crea_cert "RCA.key" "RCA.crt" "SRV.csr" "SRV.crt"



## CLIc certificate
echo "=====================================CLI----------------------------------"
crea_key "CLI.key"
crea_csr "CLI.key" "CLI.csr" "/C=CA/L=rhill/O=coinscode/CN=screen.webhop.CLI"
crea_cert "RCA.key" "RCA.crt" "CLI.csr" "CLI.crt"

#openssl pkcs12 -export -passout pass:12345678 -in certs/CLI.crt -inkey private/CLI.key -certfile certs/RCA.crt -out certs/CLIcert.p12 # export cli cert to p12

# SSLCertificateFile myCA/certs/SRV.crt
# SSLCertificateKeyFile myCA/private/winterfell.key
# SSLCertificateChainFile myCA/certs/RCA.crt
# SSLCACertificateFile myCA/certs/RCA.crt

popd


After running above script look in

OUT/certs     [CLI.crt RCA.crt and SRV.crt]
OUT/private   [CLI.key RCA.key and SRV.key]

Apache2 server (Enable SSL) / Ubuntu /Debian

Add at the end of the file: /etc/apache2.conf

<IfModule mod_ssl.c>
    ErrorLog /var/log/apache2/ssl_engine.log
    LogLevel debug
 </IfModule>


  
Create a folder: 

mkdir /etc/apache2/ssl

Copy SRV.* and RCA.* to /etc/apache2/ssl

root@comrn:/etc/apache2/ssl# ls
RCA.crt  RCA.key SRV.crt  SRV.key

Edit /etc/apache2/sites-available/000-default.conf 

<VirtualHost *:80>
        DocumentRoot /var/www/marius
        ServerName yourdomain.mine.nu
</VirtualHost>


<VirtualHost *:443>
        DocumentRoot /var/www/yourdomain
        ServerName yourdomain.mine.nu
        DirectoryIndex index.html index.php

        SSLEngine On
        SSLCertificateFile /etc/apache2/ssl/SRV.crt
        SSLCertificateKeyFile /etc/apache2/ssl/SRV.key
        SSLCACertificateFile /etc/apache2/ssl/RCA.crt
        SSLVerifyClient none
        SSLOptions StrictRequire

    <Location />
        SSLRequireSSL On
        SSLVerifyClient none
        SSLVerifyDepth 1
    </Location>
</VirtualHost>

Place a file index.html in /var/www/yourdomain
chown yourname:yourname /var/www/
mkdir -p /var/www/yourname
echo "hello from html" > /var/www/yourname/index.html

Restart apache. 

Access https://yourdomain.mine.nu with a browser.

All implementation of ssl client and server can be explored at:
https://github.com/comarius/buflea



 

 

 

 



 

 

 

 

 



No comments:

Post a Comment