2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 * Copyright (C) 2009 Jason J.A. Stephenson <jason@sigio.com>
17 * Extensively modified by Scott McKellar <scott@esilibrary.com>
18 * Copyright 2009 Equinox Software Inc.
23 @brief Routines to calculate SHA1 and MD5 digests of strings.
28 #include <gnutls/gnutls.h>
29 #include "opensrf/utils.h"
30 #include "opensrf/osrf_digest.h"
32 static void format_hex( char* buf, const unsigned char* s, size_t n );
35 @brief Calculate an SHA1 digest for a specified string.
36 @param result Pointer to an osrfSHA1Buffer to receive the result.
37 @param str Pointer to a nul-terminated string to be digested.
39 void osrf_sha1_digest( osrfSHA1Buffer* result, const char *str ) {
43 result->hex[0] = '\0';
46 size_t out_size = sizeof( result->binary ); /* SHA1 is 160 bits output. */
49 in.data = (unsigned char*) str;
50 in.size = strlen( str );
51 if( gnutls_fingerprint( GNUTLS_DIG_SHA1, &in, result->binary, &out_size )
52 == GNUTLS_E_SUCCESS ) {
53 format_hex( result->hex, result->binary, out_size );
59 @brief Calculate an SHA1 digest for a formatted string.
60 @param result Pointer to an osrfSHA1Buffer to receive the result.
61 @param str Pointer to a printf-style format string. Subsequent arguments, if any, are
62 formatted and inserted into the string to be digested.
64 void osrf_sha1_digest_fmt( osrfSHA1Buffer* result, const char* str, ... ) {
66 VA_LIST_TO_STRING( str );
67 osrf_sha1_digest( result, VA_BUF );
69 result->hex[0] = '\0';
73 @brief Calculate an MD5 digest for a specified string.
74 @param result Pointer to an osrfMD5Buffer to receive the result.
75 @param str Pointer to a nul-terminated string to be digested.
77 void osrf_md5_digest( osrfMD5Buffer* result, const char *str ) {
81 result->hex[0] = '\0';
84 size_t out_size = sizeof( result->binary ); /* MD5 is 128 bits output. */
87 in.data = (unsigned char*) str;
88 in.size = strlen( str );
89 if( gnutls_fingerprint( GNUTLS_DIG_MD5, &in, result->binary, &out_size )
90 == GNUTLS_E_SUCCESS ) {
91 format_hex( result->hex, result->binary, out_size );
97 @brief Calculate an MD5 digest for a formatted string.
98 @param result Pointer to an osrfMD5Buffer to receive the result.
99 @param str Pointer to a printf-style format string. Subsequent arguments, if any, are
100 formatted and inserted into the string to be digested.
102 void osrf_md5_digest_fmt( osrfMD5Buffer* result, const char* str, ... ) {
104 VA_LIST_TO_STRING( str );
105 osrf_md5_digest( result, VA_BUF );
107 result->hex[0] = '\0';
111 @brief Translate a series of bytes to the corresponding hexadecimal representation.
112 @param buf Pointer to the buffer that will receive the output hex characters.
113 @param s Pointer to the input characters to be translated.
114 @param n How many input characters to translate.
116 The calling code is responsible for providing a large enough output buffer. It should
117 be twice as large as the buffer to be translated, plus one for a terminal nul.
119 static void format_hex( char* buf, const unsigned char* s, size_t n ) {
121 for( i = 0; i < n; ++i ) {
122 unsigned char c = s[i];
124 // Format high nybble
125 unsigned char fc = ( c >> 4 ) & 0x0F;
126 fc += (fc > 9) ? 'a' - 10 : '0';
131 fc += (fc > 9) ? 'a' - 10 : '0';