/* compile with: * cc -W -Wall -O3 -pipe -s -o sha512 sha512.c -lcrypto */ #include #include #include #include #include #include int main () { const char *filename = "/etc/passwd"; int fd; ssize_t len; char data[4096]; EVP_MD_CTX *sha512; unsigned char sha512_md[EVP_MAX_MD_SIZE]; unsigned int sha512_len; EVP_ENCODE_CTX *base64; unsigned char base64_md[((EVP_MAX_MD_SIZE + 2) * 4) / 3 + 1]; int base64_len; char *newline; if (!(sha512 = EVP_MD_CTX_new())) errx(-1, "EVP_MD_CTX_new()"); if (!EVP_DigestInit_ex(sha512, EVP_sha512(), NULL)) errx(-1, "EVP_DigestInit_ex()"); if ((fd = open(filename, O_RDONLY)) < 0) err(-1, "open(): %s", filename); while (1) { len = read(fd, data, sizeof(data)); if (len < 0) err(-1, "read(): %s", filename); if (len == 0) break; if (!EVP_DigestUpdate(sha512, data, len)) errx(-1, "EVP_DigestUpdate()"); } if (close(fd)) err(-1, "close(): %s", filename); if (!EVP_DigestFinal_ex(sha512, sha512_md, &sha512_len)) errx(-1, "EVP_DigestInit_ex()"); EVP_MD_CTX_free(sha512); if (!(base64 = EVP_ENCODE_CTX_new())) errx(-1, "EVP_ENCODE_CTX_new()"); EVP_EncodeInit(base64); #if 0 Avoid newlines - either: base64->flags = 1; or: evp_encode_ctx_set_flags(base64, 1); #endif if (!EVP_EncodeUpdate(base64, base64_md, &base64_len, sha512_md, sha512_len)) errx(-1, "EVP_EncodeUpdate()"); if ((base64_len < 0) || (base64_len >= (signed) sizeof(base64_md))) errx(-1, "base64_len: %i", base64_len); EVP_EncodeFinal(base64, &base64_md[base64_len], &base64_len); EVP_ENCODE_CTX_free(base64); /* maybe we should use our own base64 encoder instead of OpenSSL */ while ((newline = strchr((char*) base64_md, '\n'))) memmove(newline, newline + 1, strlen(newline)); puts((char*) base64_md); return 0; }