title: sha1 example in C using openssl library
body: <p>I have a simplest possible example of <code>sha256</code> written in C, using the openSSL library.</p>
  
  <pre><code>// compile with: gcc -o sha256 sha256.c -lcrypto
  
  #include &lt;openssl/sha.h&gt;
  #include &lt;stdio.h&gt;
  int main(int argc, char **argv)
  {
      unsigned char buffer[BUFSIZ];
      FILE *f;
      SHA256_CTX ctx;
      size_t len;
      if (argc &lt; 2) {
          fprintf(stderr, "usage: %s &lt;file&gt;\n", argv[0]);
          return 1;
      }
  
      f = fopen(argv[1], "r");
      if (!f) {
          fprintf(stderr, "couldn't open %s\n", argv[1]);
          return 1;
      }
  
      SHA256_Init(&amp;ctx);
  
      do {
          len = fread(buffer, 1, BUFSIZ, f);
          SHA256_Update(&amp;ctx, buffer, len);
      } while (len == BUFSIZ);
  
      SHA256_Final(buffer, &amp;ctx);
  
      fclose(f);
  
      for (len = 0; len &lt; SHA256_DIGEST_LENGTH; ++len)
          printf("%02x", buffer[len]);
      putchar('\n');
      return 0;
  }
  </code></pre>
  
  <p>I need the same for <code>sha1</code>, but I could not find similar simple example that actually works. The naive approach of replacing occurrences of <code>SHA256</code> in the above code with <code>SHA1</code> does not work (obviously).</p>
  
  <p>How can I modify my program for <code>SHA1</code> ?</p>
  
  <h1>UPDATE</h1>
  
  <p>as suggested by @dbush, I have used his <code>EVP</code> code, and integrated it into my program. My program now looks like this:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;openssl/sha.h&gt;
  #include &lt;openssl/evp.h&gt;
  #include &lt;openssl/err.h&gt;
  
  int main(int argc, char **argv)
  {
  
  FILE *f;
  size_t len;
  unsigned char buffer[BUFSIZ];
  
  if (argc &lt; 2) {
      fprintf(stderr, "usage: %s &lt;file&gt;\n", argv[0]);
      return 1;
  }
  
  f = fopen(argv[1], "r");
  
  if (!f) {
      fprintf(stderr, "couldn't open %s\n", argv[1]);
      return 1;
  }
  
  
  EVP_MD_CTX hashctx;
  //EVP_MD *hashptr = EVP_get_digestbyname("SHA256");
  EVP_MD *hashptr = EVP_get_digestbyname("SHA1");
  
  EVP_MD_CTX_init(&amp;hashctx);
  EVP_DigestInit_ex(&amp;hashctx, hashptr, NULL));
  
  do {
      len = fread(buffer, 1, BUFSIZ, f);
      EVP_DigestUpdate(&amp;hashctx, buffer, len);
  } while (len == BUFSIZ);
  
  EVP_DigestFinal_ex(&amp;hashctx, buffer, &amp;len);
  EVP_MD_CTX_cleanup(&amp;hashctx);
  
  fclose(f);
  
  int i;
  for (i = 0; i &lt; len; ++i)
      printf("%02x", buffer[i]);
  
      return 0;
  }
  </code></pre>
  
  <p>When I compile it using <code>gcc -o evp evp.c -lcrypto</code>, I get couple of errors, such as:</p>
  
  <pre><code>evp.c: In function ‘main’:
  evp.c:29:19: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
  evp.c:32:43: error: expected ‘;’ before ‘)’ token
  evp.c:32:43: error: expected statement before ‘)’ token
  evp.c:39:1: warning: passing argument 3 of ‘EVP_DigestFinal_ex’ from incompatible pointer type [enabled by default]
  In file included from evp.c:4:0:
  /usr/include/openssl/evp.h:574:5: note: expected ‘unsigned int *’ but argument is of type ‘size_t *’
  </code></pre>