i cannot find bug in this c code

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • nbehery
    New Member
    • Apr 2015
    • 1

    #1

    i cannot find bug in this c code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/time.h>
    #include <openssl/pem.h>
    #include <openssl/rand.h>

    int my_better_rand_ bytes(unsigned char *buf, int num_bytes);
    void seed_randomness ();

    int main (int argc, char *argv[])
    {

    // Normal house keeping
    char *priv_key_file = "q1_privkey.pri v";
    char *pub_key_file = "q1_pubkey.pub" ;
    FILE *fp;
    int num_bits = 2048;

    // This is a recommend public exponent everyone uses. 65537.
    unsigned long exponent = RSA_F4;

    // Those openssl guys are CHUMPS. Did you see that debian bug? What the
    // heck. I don't trust them, I'm going to write my own random
    // implementation. That way I know it will be secure.

    // Hmm, in openssl lingo the way you generate random numbers is with a
    // RAND_METHOD Looks like I need to create my own RAND_METHOD structure. It
    // has a bunch of stuff in it, but the only really important parts are the
    // pseudrand and rand members.
    RAND_METHOD my_better_rando m_method;

    // Part of the house keeping is I need to clear the struct
    memset(&my_bett er_random_metho d, 0x00, sizeof(RAND_MET HOD));


    // From the openssl man pages it looks liked I need to set two key functions:
    // pseudorand which behaves like RAND_pseudo_byt es, and
    // bytes which behaves like RAND_bytes.
    // man page: http://linux.die.net/man/3/rand_bytes
    // In my implementation, all bytes are pseudorandom, so these are the same
    my_better_rando m_method.pseudo rand = my_better_rand_ bytes;
    my_better_rando m_method.bytes = my_better_rand_ bytes;

    // Okies I built my random method, now I just need tell openssl to use it
    RAND_set_rand_m ethod(&my_bette r_random_method );

    // Seed my random function...
    seed_randomness ();

    // Finally I can sleep at night.

    // Create our key
    RSA *rsa = RSA_generate_ke y(num_bits,expo nent,NULL,NULL) ;

    // The RSA structure has all our important fields. n, e, d, p, q, etc.
    // struct
    // {
    // BIGNUM *n; // public modulus
    // BIGNUM *e; // public exponent
    // BIGNUM *d; // private exponent
    // BIGNUM *p; // secret prime factor
    // BIGNUM *q; // secret prime factor
    // BIGNUM *dmp1; // d mod (p-1)
    // BIGNUM *dmq1; // d mod (q-1)
    // BIGNUM *iqmp; // q^-1 mod p
    // // ...
    // };
    // RSA
    // http://www.openssl.org/docs/crypto/rsa.html
    // But even with all those fields, n is enough to uniquely match a public and
    // private keypair.
    //
    // BIGNUM's are hard to work with directly, though. You have to use things like
    // BN_cmp().
    // http://www.openssl.org/docs/crypto/BN_cmp.html

    // Write out the private key
    if (!(fp = fopen(priv_key_ file, "w"))){
    fprintf(stderr, "Could not open private key file %s\n", priv_key_file);
    exit(1);
    }

    // openssl has this handy function to write out our private key in the correct format. Awesome.
    if (!PEM_write_RSA PrivateKey( fp, // Output file
    rsa, // Our private key
    NULL,NULL,0,NUL L,NULL // Houekeeping
    )
    ){
    fprintf(stderr, "Could not write private key file %s\n", priv_key_file);
    exit(1);
    }

    // Write out the public key
    if (!(fp = fopen(pub_key_f ile, "w"))){
    fprintf(stderr, "Could not open public key file %s\n", pub_key_file);
    exit(1);
    }

    // Just like the private key, the public key can be written by openssl
    if (!PEM_write_RSA PublicKey(fp, rsa))
    {
    fprintf(stderr, "Could not write public key file %s\n", pub_key_file);
    exit(1);
    }

    // OpenSSL has a corresponding read function, it looks like: PEM_read_RSAPub licKey

    exit(0); // Security Success!

    }

    // K&R are awesome guys. I once got a chance to meet them. I'm sure their
    // random number generation is cryptographical ly secure, given an unguessable
    // seed. Let's just use their rand() call.
    int my_better_rand_ bytes(unsigned char *buf, int num_bytes)
    {

    for (int i = 0; i < num_bytes; i+=4)
    {
    int rand_int = rand();
    memcpy(buf + i, &rand_int, num_bytes - i);
    }

    return 1; // 1 means good!
    }

    // For the standard C rand I need to seed it with srand()...
    void seed_randomness ()
    {
    // my_better_rand_ bytes needs a seed for my random function. I need
    // something random and unguessable... how about the system time when I
    // turn on the program?

    struct timeval t;
    gettimeofday(&t , NULL);

    unsigned int time_in_sec = t.tv_sec; // Current seconds since epoc (midnight, jan 1, 1970)
    unsigned int time_micro_sec = t.tv_usec; // Number of microseconds this second
    unsigned int seed;

    // Set the seed to the number of seconds since epoc
    seed = time_in_sec;

    // Add to that the number of milli-seconds
    seed = time_micro_sec >> 7;

    srand(seed); // Unguessable!
    }
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    What bug would that be?

    Comment

    • Luuk
      Recognized Expert Top Contributor
      • Mar 2012
      • 1043

      #3
      and why did you not use [CODE/] tags around you code?

      Comment

      Working...