#pragma module SSL$SHA1_MD5 "V1.0" /* ** Copyright 2004 Hewlett-Packard Development Company, L.P. ** ** Confidential computer software. Valid license from HP and/or its ** subsidiaries required for possession, use, or copying. ** ** Consistent with FAR 12.211 and 12.212, Commercial Computer Software, ** Computer Software Documentation, and Technical Data for Commercial ** Items are licensed to the U.S. Government under vendor's standard ** commercial license. ** ** Neither HP nor any of its subsidiaries shall be liable for technical ** or editorial errors or omissions contained herein. The information ** in this document is provided "as is" without warranty of any kind ** and is subject to change without notice. The warranties for HP ** products are set forth in the express limited warranty statements ** accompanying such products. Nothing herein should be construed as ** constituting an additional warranty. ** **++ ** FACILITY: ** ** Secure Sockets Layer (SSL) for OpenVMS ** ** MODULE DESCRIPTION: ** ** SSL$SHA1_MD5.C ** ** ABSTRACT: ** ** This example uses SSL crypto library SHA1 or MD5 message disgest ** EVP application program interface calls to perform a one way hash ** on the input buffer data "input1" and "input2". The resulting hashed ** output in "digest" is then printed in hex format to the terminal. ** Any digest output data that represents an ASCII character in the range ** from a space character to a tilde character, (decimal 32 -- 126), are ** also printed. Others are represented as a space character. ** ** To enable a different digest (for example, MD5), instead of the default ** SHA1 digest, please refer to the section: ** ** "Build Configuration and Run Instructions" ** ** ENVIRONMENT: (Minimal Versions) ** ** OpenVMS V8.2 Alpha or Itanium, or OpenVMS V7.3 VAX ** SSL for OpenVMS V1.2 ** ** AUTHOR: ** ** V1.0 Paul Mosteika CREATION DATE: 28-Sep-2004 ** OpenVMS Engineering Security Group ** ** MODIFICATION HISTORY: ** **-- */ /* Build, Configuration, and Run Instructions */ /* ** BUILD INSTRUCTIONS: ** ** To build this example program use commands of the form, ** using the "DECC" compiler: ** ** To Create a 32-bit Application Using 32-bit SSL APIs ** ---------------------------------------------------- ** ** $ CC /POINTER=32 /PREFIX=ALL SSL$SHA1_MD5.C ** $ LINK SSL$SHA1_MD5.OBJ , SYS$INPUT:/OPT ** SYS$LIBRARY:SSL$LIBCRYPTO_SHR32.EXE /SHARE ** SYS$LIBRARY:SSL$LIBSSL_SHR32.EXE /SHARE ** $ ^z ** ** To Create a 64-bit Application Using 64-bit SSL APIs ** ---------------------------------------------------- ** ** $ CC /POINTER=64/PREFIX=ALL SSL$SHA1_MD5.C ** $ LINK SSL$SHA1_MD5.OBJ , SYS$INPUT:/OPT ** SYS$LIBRARY:SSL$LIBCRYPTO_SHR.EXE /SHARE ** SYS$LIBRARY:SSL$LIBSSL_SHR.EXE /SHARE ** $ ^z ** ** Note, to enable the MD5 digest change one of the following: ** --- ** o the definition in this source code ** ** #DEFINE DIGEST_DEFAULT "md5" ** ** o or enter the digest name as a paramter when running this program ** ** $ mcr []SSL$SHA1_MD5 "md5" ** ** Other digests that may be available are: ** ** "md2" , "md4" , "sha" , and "ripemd160" ** ** CONFIGURATION INSTRUCTIONS: ** ** SSL for OpenVMS must be installed and started. ** ** RUN INSTRUCTIONS: ** ** To run this example program: ** ** $ run SSL$SHA1_MD5 ! SHA1 is used by default ** - or - ** $ mcr SSL$SHA1_MD5 "md5" ! MD5 disgest is used */ /* ** INCLUDE FILES: */ #include #include #include #include #include "SSL$INCLUDE:EVP.H" #define BUF_SIZE1 100 #define BUF_SIZE2 59 char *argv_digest; #define DIGEST_DEFAULT "sha1" /* ** Macro(s) */ #define check(status,string) \ if (status != 1) { printf("%s\n", string); lib$stop (status); } int main ( int argc , char *argv[] ) { /* ** 20 Bytes = SHA1, 16 Bytes = MD5, EVP_MAX_MD_SIZE = 20 + 16 Bytes */ unsigned char digest[EVP_MAX_MD_SIZE]; /* Digest O/P */ char *input1, *input2; /* Input to digest */ EVP_MD_CTX ctx; /* Digest ctx to init */ const EVP_MD *md = NULL, *m; /* Digest Pointer */ int i ; /* Loop control */ int ret = 0; /* Returned status */ unsigned int count = 0; /* Byte count of digest */ /* ** Allocate and preset input buffer data */ input1 = malloc(BUF_SIZE1); memset(input1, 'A', BUF_SIZE1); input2 = malloc(BUF_SIZE2); memset(input2, 'Z', BUF_SIZE2); /* ** Add all known digests or else EVP_get_digestbyname() fails */ OpenSSL_add_all_digests(); /* ** Convert/copy input arg[1] (digest name) to 64 bits. ** For 32 bits we gain nothing. This is necessary when passing ** pointers and when compiled in 64-bit mode. DCL currently ** passes only 32 bit argc, *argv[] to the DECC RTL and main(). ** However, other pointers are 64 bits when compiled /pointer=64. ** Also, note that certain DECC RTL functions are restricted to ** 32-bit mode. */ argv_digest = argv[1]; /* ** Check if user specified a digest name as an input argument */ if ( argv_digest != NULL ) { m = EVP_get_digestbyname( argv_digest ); if ( m != NULL ) { md = m ; } else /* Error */ { ret = 0; printf("\n Digest %s is unknown. \n", argv_digest ); check(ret,"\n\t !!! EVP_get_digestbyname() Failure - bad digest !!! \n"); } } else { /* ** Otherwise use default digest */ m = EVP_get_digestbyname( DIGEST_DEFAULT ); if ( m != NULL ) { md = m ; } else { ret = 0; printf("\n Digest %s is unknown. \n", DIGEST_DEFAULT ); check(ret,"\n\t !!! EVP_get_digestbyname() Failure - bad digest !!! \n"); } } printf("\n We are using a digest of %d bytes \n" , EVP_MD_size(md) ); /* ** Initialize the context or else EVP_DigestInit_ex() can fail */ EVP_MD_CTX_init( &ctx ); /* ** Initialize the digest once we have a context and digest name */ ret = EVP_DigestInit_ex( &ctx , md , NULL ); check( ret , "\n\t !!! EVP_DigestInit_ex() Failure !!! \n"); /* ** Perform the hash on the input data buffer 1, then 2 */ ret = EVP_DigestUpdate( &ctx , input1 , BUF_SIZE1 ); check( ret , "\n\t !!! EVP_DigestUpdate() Failure Part1 !!! \n"); ret = EVP_DigestUpdate( &ctx , input2 , BUF_SIZE2 ); check( ret , "\n\t !!! EVP_DigestUpdate() Failure Part2 !!! \n"); /* ** Finalize to get the result in the digest array */ ret = EVP_DigestFinal_ex( &ctx , digest , &count ); check( ret , "\n\t !!! EVP_DigestFinal_ex() Failure !!! \n"); /* ** Cleanup the context when done with all data to digest */ EVP_MD_CTX_cleanup( &ctx ); /* ** Print input buffers and resulting digest */ printf("\n For the %d input characters of:\n%s%s\n", BUF_SIZE1+BUF_SIZE2 , input1 , input2); printf("\n\n We have the %d byte code digest :\n", count ); for ( i=0; i= 32 && digest[i]<=126) ? digest[i] : ' '); } printf("\n"); }