1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

OpenSSL tutorials

Discussion in 'Entertainment and Technology' started by lssl, Jan 11, 2014.

  1. lssl

    lssl Guest

    I'm currently working on a program that uses encryption to communicate privately over sockets. I've looked through a few libraries and have settled on OpenSSL as it's widely used, cross-platform, and seems to give more access to lower level APIs than others which abstract away a lot of the process (I'm looking at you PolarSSL). The problem I've found is that OpenSSL's documentation seems to be notoriously bad. I've found some good scraps on their wiki but does anyone know of any more complete resources for using OpenSSL?
     
  2. starfish

    Full Member

    Joined:
    Nov 11, 2008
    Messages:
    3,368
    Likes Received:
    0
    Location:
    Hippie Town, Alberta of the US
  3. lssl

    lssl Guest

    Oh dear, I had a feeling I would have to pick up an actual physical book. Haven't done that in ages. :lol: I'll see if I can find it in the library around here. I guess another relevant question would be does anyone know of other cryptographic libraries that allow you to use Diffie Hellman key exchange and such without using the full-blown SSL protocol? I know OpenSSL does but then again the documentation seems to be quite lacking.
     
  4. Pret Allez

    Full Member

    Joined:
    Apr 19, 2012
    Messages:
    6,785
    Likes Received:
    67
    Location:
    Seattle, WA
    Gender:
    Female (trans*)
    Gender Pronoun:
    She
    Sexual Orientation:
    Bisexual
    Out Status:
    Some people
    Why can't we just use this?

    I think this is basically the exchange, right?

    I could be wrong, though. I'm only a youngling beginner cipherpunk, so ya...
     
    #4 Pret Allez, Jan 12, 2014
    Last edited: Jan 12, 2014
  5. lssl

    lssl Guest

    That was actually the exact page that I stumbled upon. I think that's ultimately what I'm going to use but I just wish they were a little bit more transparent on parameter agreement. I'm a little confused with what they mean on the wiki by either using standard parameters or generating your own. I get what generating your own parameters from scratch is but are standard parameters values randomly chosen from a list of acceptable parameter values? Couldn't that potentially be a security vulnerability if that were the case?
     
  6. Pret Allez

    Full Member

    Joined:
    Apr 19, 2012
    Messages:
    6,785
    Likes Received:
    67
    Location:
    Seattle, WA
    Gender:
    Female (trans*)
    Gender Pronoun:
    She
    Sexual Orientation:
    Bisexual
    Out Status:
    Some people
    I'm not sure how that part works, but my understanding is that you actually need to agree on more than just the DH parameters. You actually need to agree on the key exchange algorithm itself. I think OpenSSL clients and servers have cipher suite preference lists, and they support more than just DH. They also support ECDH. Are you planning to support that as well?
     
  7. lssl

    lssl Guest

    I am not. This is more an educational project for myself so I figured I'd just support DH for the time being. When I was reading about OpenSSL, I was under the impression that the cipher suite preference lists are only used when you are using full on SSL protocol as it's a part of SSL/TLS.
     
  8. Pret Allez

    Full Member

    Joined:
    Apr 19, 2012
    Messages:
    6,785
    Likes Received:
    67
    Location:
    Seattle, WA
    Gender:
    Female (trans*)
    Gender Pronoun:
    She
    Sexual Orientation:
    Bisexual
    Out Status:
    Some people
    I put blood and sweat into this code, but please take it with a grain of salt. I am probably violating cryptographic best practices I'm not even aware of. I'm an amateur, and this is not my field.

    Code:
    [COLOR="SeaGreen"]// foo.c[/COLOR]
    
    [COLOR="Sienna"]#include <assert.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/time.h>
    #include <openssl/rand.h>
    #include <openssl/dh.h>
    #include <openssl/engine.h>
    #include <openssl/evp.h> [/COLOR]
    
    [COLOR="SeaGreen"]// Compile with gcc -g --std=gnu11 -lssl -lcrypto foo.c[/COLOR]
    
    [COLOR="RoyalBlue"]void[/COLOR] seed_random();
    [COLOR="RoyalBlue"]DH*[/COLOR] dhparams();
    [COLOR="RoyalBlue"]DH*[/COLOR] gendh();
    [COLOR="RoyalBlue"]unsigned char*[/COLOR] dh_derive([COLOR="RoyalBlue"]EVP_PKEY*[/COLOR], [COLOR="RoyalBlue"]EVP_PKEY*[/COLOR], [COLOR="RoyalBlue"]size_t*[/COLOR]);
    
    [COLOR="RoyalBlue"]int[/COLOR] main([COLOR="RoyalBlue"]int[/COLOR] argc, [COLOR="RoyalBlue"]char**[/COLOR] argv) {
      seed_random();
      
      [COLOR="RoyalBlue"]DH*[/COLOR] params = dhparams();
        
      [COLOR="SeaGreen"]// This is Alicia's key.[/COLOR]
      [COLOR="RoyalBlue"]DH*[/COLOR] dh_alicia = gendh(params);
      
      [COLOR="SeaGreen"]// This is Beth's key.[/COLOR]
      [COLOR="RoyalBlue"]DH*[/COLOR] dh_beth = gendh(params);
      
      [COLOR="RoyalBlue"]EVP_PKEY*[/COLOR] key_alicia = EVP_PKEY_new();
      EVP_PKEY_set1_DH(key_alicia, dh_alicia);
      
      [COLOR="RoyalBlue"]EVP_PKEY*[/COLOR] key_beth = EVP_PKEY_new();
      EVP_PKEY_set1_DH(key_beth, dh_beth);
      
      [COLOR="RoyalBlue"]size_t[/COLOR] key_len = 0;
      [COLOR="SeaGreen"]// Compute the shared secret using Alicia's private key and Beth's public key.[/COLOR]
      [COLOR="RoyalBlue"]unsigned char*[/COLOR] key1 = dh_derive(key_alicia, key_beth, &key_len);
      [COLOR="SeaGreen"]// Compute the shared secret using Beth's private key and Alicia's public key.[/COLOR]
      [COLOR="RoyalBlue"]unsigned char*[/COLOR] key2 = dh_derive(key_beth, key_alicia, &key_len);
      
      [COLOR="SeaGreen"]// Prove correctness by showing Alicia and Beth derived the same secret[/COLOR]
      assert(memcmp(key1, key2, key_len) == 0);
      
      DH_free(params);
      DH_free(dh_alicia);
      DH_free(dh_beth);
      EVP_PKEY_free(key_alicia);
      EVP_PKEY_free(key_beth);
      free(key1);
      free(key2);
      
      [COLOR="RoyalBlue"]return[/COLOR] 0; }
    
    [COLOR="RoyalBlue"]void[/COLOR] seed_random() {
    [COLOR="SeaGreen"]  // Seed the cryptographically secure pseudo random number generator.
      // I don't know how to do this well, so I am going to hope that we're
      // statistically unlikely to know EXACTLY how long the main thread is
      // REALLY going to wait if I call usleep eight times. We hope that
      // reading the microseconds off the CPU will be sufficiently unpredictable.
      // Maybe the coding security experts at EC have a better idea?[/COLOR]
      [COLOR="RoyalBlue"]char*[/COLOR] seed = malloc(64);
      [COLOR="RoyalBlue"]struct timeval[/COLOR] reading;
      [COLOR="RoyalBlue"]for[/COLOR]([COLOR="RoyalBlue"]int[/COLOR] i = 0; i < 8; ++i) {
        gettimeofday(&reading, 0);
        memcpy(seed+i*8, &reading.tv_usec, 8);
        usleep(4972); }
        
      RAND_set_rand_engine(ENGINE_get_default_RAND());
      RAND_seed(seed, 64);
      free(seed); }
      
    [COLOR="RoyalBlue"]DH*[/COLOR] dhparams() {
      [COLOR="RoyalBlue"]DH*[/COLOR] dh = DH_new();
      DH_generate_parameters_ex(dh, 1024, DH_GENERATOR_5, 0); 
      [COLOR="RoyalBlue"]return[/COLOR] dh; }
      
    [COLOR="RoyalBlue"]DH*[/COLOR] gendh([COLOR="RoyalBlue"]DH*[/COLOR] params) {
      [COLOR="RoyalBlue"]DH*[/COLOR] dh = DHparams_dup(params);
      DH_generate_key(dh);
      [COLOR="RoyalBlue"]return[/COLOR] dh; }
      
    [COLOR="RoyalBlue"]unsigned char*[/COLOR] dh_derive([COLOR="RoyalBlue"]EVP_PKEY*[/COLOR] secret, [COLOR="RoyalBlue"]EVP_PKEY[/COLOR]* peer, [COLOR="RoyalBlue"]size_t*[/COLOR] len) {
      [COLOR="RoyalBlue"]unsigned char*[/COLOR] derived_key = 0;
      
      [COLOR="RoyalBlue"]EVP_PKEY_CTX*[/COLOR] ctx = EVP_PKEY_CTX_new(secret, ENGINE_get_default_DH());
      EVP_PKEY_derive_init(ctx);
      EVP_PKEY_derive_set_peer(ctx, peer);
      
      EVP_PKEY_derive(ctx, 0, len);
      
      derived_key = malloc(*len);
      
      EVP_PKEY_derive(ctx, derived_key, len);
      EVP_PKEY_CTX_free(ctx);
      
      [COLOR="RoyalBlue"]return[/COLOR] derived_key; }
    
     
    #8 Pret Allez, Jan 14, 2014
    Last edited: Jan 14, 2014
  9. Pret Allez

    Full Member

    Joined:
    Apr 19, 2012
    Messages:
    6,785
    Likes Received:
    67
    Location:
    Seattle, WA
    Gender:
    Female (trans*)
    Gender Pronoun:
    She
    Sexual Orientation:
    Bisexual
    Out Status:
    Some people
    So, in my example, you can see that I generate Diffie-Hellman parameters once, and I use them twice for both keys, but this setup isn't very realistic. Since you're writing a network application, you'll probably have something like this:

    1) Alicia generates a DH struct and generates Diffie-Hellman parameters in it. She generates a copy of this structure, zeros out dh->priv_key and sends the structure over the unsecured network.

    2) Beth is listening. She generates a DH struct and copies Alicia's DH parameters into it by calling DHparams_dup(). She also saves off Alicia's dh->pub_key

    3) Beth now generates her own key using her DH struct and DH_generate_key(). She sends Alicia her own dh->pub_key.

    4) Now Alicia and Beth have one another's public keys and the same Diffie-Hellman parameters, so they can derive a shared secret.
     
    #9 Pret Allez, Jan 14, 2014
    Last edited: Jan 14, 2014
  10. lssl

    lssl Guest

    Wow thank you so much! I really appreciate you taking the time to do this. I'll keep looking into this. The application I'm working on is essentially an ssh clone that I'm building from scratch to teach myself about fundamentals of linux programming (fork, pseudoterminals, etc) with some cryptography thrown in there. I've currently run into some issues with changing the winsize attribute of the terminal on the remote machine when the client resizes the terminal emulator. I looked through the ssh code and figured out how they did that so now it's just a matter of implementing it within my own heavily simplified framework. All that to say thank you again and I will take a harder look at your code once I'm done with my current issue.
     
  11. chivalrous

    Full Member

    Joined:
    Dec 30, 2013
    Messages:
    60
    Likes Received:
    0
    Location:
    Australia, Victoria
    If worse comes to worse just consult stack exchange. hehehehe :stuck_out_tongue_closed_eyes:
     
  12. Pret Allez

    Full Member

    Joined:
    Apr 19, 2012
    Messages:
    6,785
    Likes Received:
    67
    Location:
    Seattle, WA
    Gender:
    Female (trans*)
    Gender Pronoun:
    She
    Sexual Orientation:
    Bisexual
    Out Status:
    Some people
    90% of the time I find an "answer" on Stack Exchange, people are not telling you what to do or where to look at all. They ask "do you really need to do that?" and "why are you doing that?" and then tell you "don't do that." They are pretty useless.