Handy Notes on SSL handshake between client and server

1. symmetric key encryption

server                  client
key+email            key+email

in symmetric key encrption, the message encrpypted by server by a key needs to be shared with client
which can only decrypt the message with the key shared by server.

Problem: any hacker in the middle can read the packet and get the key and dycrypt the message himself.


2. asymmetric key encryption: 
First, generate an asymmetric key pair (public key+private key pair) for user 1 and user 2.

user 1                                  user2
public_key_user1                public_key_user2
private_key_user1               private_key_user2

Now, user1 and user2 both share their public keys. Public keys visible to whole internet
and private keys would be with the user alone.

user 1                                  user 2
public_key_user2                public_key_user1

the message encrpyted by public_key_user2 can only be decrypted by private_key_user2.

So, if user 1 is send the message to user 2 by encrpting it with public_key_user2,
only user 2 can unlock it with his private key (private_key_user2) and not even user1
can decrypt it.

in short, a message encrypted with an asymmetric public key can only be decrypted with
it other key pair i.e. asymmetric private key.


3. Prepare digital certificate for both user 1 and user 2 that should be signed by the CA.the certificates can also be signed by user himself.

   the digital certificate has following info:
   1. data: version and serial no.
   2. Signature algorithm
   3. Issuer of the certificate
   4. Validity of the certificate
   5. Subject of the certificate
   6. PUBLIC KEY (this is important. the public key is saved in this digital certificate)
   7. Signature Algorithm

4. Goint back to point 2:

First, generate an asymmetric key pair (public key+private key pair) for user 1 and user 2.

<CLIENT>                        <SERVER>
user 1                                  user2
public_key_user1                public_key_user2
private_key_user1               private_key_user2


1. < CLIENT HELLO >
Now, user1 and user2 both share their public keys. Public keys visible to whole internet
and private keys would be with the user alone.

user 2
public_key_user1


2. < SERVER HELLO >
user 1
public_key_user2

3. < CLIENT: AUTHENTICATION AND PRE-MASTER SECRET >
generate pre-master key.
encrypt the pre-master key with public_key_user2 and send it to user to so that only user 2 can
decrypt it as it has the private key to decrypt it.

4. <SERVER: DECRYPTION AND MASTER SECRET>
user 2 on receiving the message decrypts it using private_key_user2
and gets the pre-master key that user 1 has encrypted into the message.
Now, user 2 has agreed that it would use this master key to for further communication.

5. <ENCRYPTION WITH SESSION KEY>

uptill point 4, the encrption and decryption algorithm used are asymmetric.
Now that user 1 and user 2 have agreed upon the master key only know to both of them,
both will use this master key to encrpt and decrypt the message.

So, the encryption and decryption from here on would be symmetric.


$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Now, we need to interpret the above 5 stages in language of digital certificates:
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


REFER:
https://www.websecurity.symantec.com/security-topics/how-does-ssl-handshake-work
https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs


A "Root SSL certificate" is a certificate issued by a trusted certificate authority (CA).

In the SSL ecosystem, anyone can generate a signing key and sign a new certificate with that signature.
However, that certificate is not considered valid unless it has been directly or indirectly signed by a trusted CA.

A trusted certificate authority is an entity that has been entitled to verify that someone is effectively who it declares to be.
In order for this model to work, all the participants on the game must agree on a set of CA which they trust.

##########################################################################################################################
##########################################################################################################################
** Browsers and/or operating systems tend to come with a pre-defined list of CA certificates
used as "trust anchors" to check the certificates of servers they connect to.
##########################################################################################################################
##########################################################################################################################


###########################################################################################
How this is done in the code:
###########################################################################################

https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_load_verify_locations.html

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
SSL_CTX_load_verify_locations: set default locations for trusted CA certificates
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
SSL_CTX_load_verify_locations() specifies the locations for ctx, at which CA certificates for verification purposes are located.
The certificates available via CAfile and CApath are trusted.
The certificates in CApath are only looked up when required, e.g. when building the certificate chain or when actually performing the verification of a peer certificate.

##########################################################################################################################
When looking up CA certificates, the OpenSSL library will first search the certificates in CAfile,
then those in CApath.
Certificate matching is done based on the subject name, the key identifier (if present), and the serial
number as taken from the certificate to be verified.If these data do not match, the next certificate will be tried.
If a first certificate matching the parameters is found,
the verification process will be performed; no other certificates for the same parameters will be searched in case of failure."
###########################################################################################################################


https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
SSL_CTX_set_verify
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
##########################################################################################################################
SSL_CTX_set_verify() sets the verification flags for ctx to be mode and specifies
the verify_callback function to be used. If no callback function shall be specified,
the NULL pointer can be used for verify_callback.
##########################################################################################################################

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
SSL_CTX_set_verify_depth()
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
##########################################################################################################################
SSL_CTX_set_verify_depth() sets the maximum depth for the certificate chain verification
that shall be allowed for ctx.

SSL_VERIFY_PEER
************
Server mode:
************
the server sends a client certificate request to the client.
The certificate returned (if any) is checked. If the verification process fails,
the TLS/SSL handshake is immediately terminated with an alert message containing
the reason for the verification failure. The behaviour can be controlled by the additional
SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
************
Client mode:
************
the server certificate is verified. If the verification process fails, the TLS/SSL
handshake is immediately terminated with an alert message containing the reason for the verification
failure. If no server certificate is sent, because an anonymous cipher is used, SSL_VERIFY_PEER is ignored.
##########################################################################################################################


SSL_get_verify_result

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
What is the SSL Certificate Chain?
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
There are two types of certificate authorities (CAs): root CAs and intermediate CAs. In order for an SSL
certificate to be trusted, that certificate must have been issued by a CA that is included in the trusted
store of the device that is connecting.

If the certificate was not issued by a trusted CA, the connecting device (eg. a web browser) will then check
to see if the certificate of the issuing CA was issued by a trusted CA, and so on until either a trusted CA
is found (at which point a trusted, secure connection will be established) or no trusted CA can be found
(at which point the device will usually display an error).

Open SSL client Server Programming 

OpenSSL – server example
OpenSSL – client example
// ssl initialization for open ssl server process  <LAYER 5,6,7>
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
if ((ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
fatalx("ctx");

// verify the location of CA certificate as well the CA certificate itself
if (!SSL_CTX_load_verify_locations(ctx, SSL_CA_CRT, NULL))
fatalx("verify");
SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(SSL_CA_CRT));

// use the certificate and private key create for server process using open ssl command
if (!SSL_CTX_use_certificate_file(ctx, SSL_SERVER_CRT, SSL_FILETYPE_PEM))
fatalx("cert");
if (!SSL_CTX_use_PrivateKey_file(ctx, SSL_SERVER_KEY, SSL_FILETYPE_PEM))
fatalx("key");
if (!SSL_CTX_check_private_key(ctx))
fatalx("cert/key");

// set the CA certificate to verified and depth to 1. Unless this is exclusively set, 
    The default value is -1.
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify_depth(ctx, 1); 

// attach ssl to TCP server socket. TCP server socket code begins here. <LAYER 4>
/* setup socket – socket()/bind()/listen() */
for (; work != 0;) {
if ((s = accept(sock, 0, 0)) == -1)
err(EX_OSERR, "accept");
sbio = BIO_new_socket(s, BIO_NOCLOSE);
ssl = SSL_new(ctx);
SSL_set_bio(ssl, sbio, sbio);
if ((r = SSL_accept(ssl)) == -1)
warn("SSL_accept");
}
// ssl initialization for open ssl client process <LAYER 5,6,7>
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
if ((ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
fatalx("ctx");

// verify the location of CA certificate as well the CA certificate itself
if (!SSL_CTX_load_verify_locations(ctx, SSL_CA_CRT, NULL))  à when this code is commented out, CA certificate validation fails and the client process would terminate the session.
fatalx("verify");


// use the certificate and private key created for client process using openssl command
if (!SSL_CTX_use_certificate_file(ctx, SSL_CLIENT_CRT, SSL_FILETYPE_PEM))
fatalx("cert");
if (!SSL_CTX_use_PrivateKey_file(ctx, SSL_CLIENT_KEY, SSL_FILETYPE_PEM))
fatalx("key");
if (!SSL_CTX_check_private_key(ctx))
fatalx("cert/key");

// set the CA certificate to verified and depth to 1. Unless this is exclusively set,
    The default value is -1.
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(ctx, 1);

// attach ssl to TCP server socket. TCP server socket code begins here. <LAYER 4>
/* setup connection */
if ((hp = gethostbyname("localhost")) == NULL)
err(EX_OSERR, "gethostbyname");
/* init socket – socket()/connect() */
/* go do ssl magic */
ssl = SSL_new(ctx);
sbio = BIO_new_socket(sock, BIO_NOCLOSE);
SSL_set_bio(ssl, sbio, sbio);
if (SSL_connect(ssl) <= 0)
fatalx("SSL_connect");
if (SSL_get_verify_result(ssl) != X509_V_OK)
fatalx("cert");
printf("connected to server!\n");
SSL_free(ssl);
BIO_free_all(sbio);
SSL_CTX_free(ctx);