|         |      1 /* | 
|         |      2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).  | 
|         |      3 * All rights reserved. | 
|         |      4 * This component and the accompanying materials are made available | 
|         |      5 * under the terms of "Eclipse Public License v1.0" | 
|         |      6 * which accompanies this distribution, and is available | 
|         |      7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      8 * | 
|         |      9 * Initial Contributors: | 
|         |     10 * Nokia Corporation - initial contribution. | 
|         |     11 * | 
|         |     12 * Contributors: | 
|         |     13 * | 
|         |     14 * Description:  A port of gnu md.c useful functions to Symbian. | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18  | 
|         |     19 /** A port of gnu md.c useful functions to Symbian **/ | 
|         |     20  | 
|         |     21 #include <stdlib.h> | 
|         |     22 #include <hash.h> | 
|         |     23 #include "xmlsecc_config.h" | 
|         |     24 #include "xmlsecc_cryptowrapper.h" | 
|         |     25 #include "xmlsec_error_flag.h" | 
|         |     26  | 
|         |     27  | 
|         |     28 /* This object is used to hold a handle to a message digest object. | 
|         |     29    This structure is private - only to be used by the public sc_md_* | 
|         |     30    macros.  */ | 
|         |     31 typedef struct sc_md_handle  | 
|         |     32 { | 
|         |     33   /* Actual context.  */ | 
|         |     34   CMessageDigest *digest; | 
|         |     35    | 
|         |     36   /* Buffer management.  */ | 
|         |     37   HBufC8 *hash; | 
|         |     38    | 
|         |     39   /* Indicate support for HMAC */ | 
|         |     40   int hmac; | 
|         |     41  | 
|         |     42 } *sc_md_hd_t; | 
|         |     43  | 
|         |     44 /**************** | 
|         |     45  * Open a message digest handle for use with algorithm ALGO. | 
|         |     46  * More algorithms may be added by md_enable(). The initial algorithm | 
|         |     47  * may be 0. | 
|         |     48  */ | 
|         |     49  | 
|         |     50 static TInt | 
|         |     51 md_open (sc_md_hd_t *h, int algo, int secure, int hmac) | 
|         |     52 { | 
|         |     53   TInt err = KErrNone; | 
|         |     54   int bufsize = secure ? 512 : 1024; | 
|         |     55   sc_md_hd_t hd; | 
|         |     56   hd = (sc_md_hd_t)malloc (sizeof (struct sc_md_handle)); | 
|         |     57   if (! hd) | 
|         |     58     err = KErrNoMemory; | 
|         |     59   if (! err) | 
|         |     60     { | 
|         |     61       /* Setup the globally visible data (bctl in the diagram).*/ | 
|         |     62       switch(algo) | 
|         |     63       { | 
|         |     64       	case SC_MD_SHA1: | 
|         |     65       		TRAP(err, hd->digest = CSHA1::NewL());  | 
|         |     66       		hd->hash = NULL; | 
|         |     67       		break; | 
|         |     68       	default: | 
|         |     69       		free(hd); | 
|         |     70 			return KErrNotSupported;	  	      		      	 | 
|         |     71       } | 
|         |     72   	  //HMAC | 
|         |     73   	  hd->hmac = hmac; | 
|         |     74     } | 
|         |     75   if (! err) | 
|         |     76   { | 
|         |     77     *h = hd;  | 
|         |     78   } | 
|         |     79   else | 
|         |     80   { | 
|         |     81     free(hd);  	 | 
|         |     82   } | 
|         |     83   return err; | 
|         |     84 } | 
|         |     85  | 
|         |     86 /* Create a message digest object for algorithm ALGO.  FLAGS may be | 
|         |     87    given as an bitwise OR of the sc_md_flags values.  ALGO may be | 
|         |     88    given as 0 if the algorithms to be used are later set using | 
|         |     89    sc_md_enable. H is guaranteed to be a valid handle or NULL on | 
|         |     90    error.  */ | 
|         |     91 TInt | 
|         |     92 sc_md_open (sc_md_hd_t *h, int algo, unsigned int flags) | 
|         |     93 { | 
|         |     94   TInt err = KErrNone; | 
|         |     95   sc_md_hd_t hd=NULL; | 
|         |     96  | 
|         |     97   if ((flags & ~(SC_MD_FLAG_SECURE | SC_MD_FLAG_HMAC))) | 
|         |     98     err = KErrArgument; | 
|         |     99   else | 
|         |    100     { | 
|         |    101  | 
|         |    102       err = md_open (&hd, algo, (flags & SC_MD_FLAG_SECURE), | 
|         |    103 		     (flags & SC_MD_FLAG_HMAC)); | 
|         |    104  | 
|         |    105     } | 
|         |    106  | 
|         |    107   *h = err? NULL : hd; | 
|         |    108   return err; | 
|         |    109 } | 
|         |    110  | 
|         |    111 /**************** | 
|         |    112  * Return the length of the digest in bytes. | 
|         |    113  * This function will return 0 in case of errors. | 
|         |    114  */ | 
|         |    115 unsigned int | 
|         |    116 sc_md_get_algo_dlen (sc_md_hd_t hd) | 
|         |    117 { | 
|         |    118  | 
|         |    119   TInt len = hd->digest->HashSize(); | 
|         |    120    | 
|         |    121   return len; | 
|         |    122 } | 
|         |    123  | 
|         |    124 const byte * | 
|         |    125 md_read(sc_md_hd_t hd) | 
|         |    126 { | 
|         |    127 	TRAPD(leaveValue,hd->hash = HBufC8::NewL(hd->digest->HashSize())); | 
|         |    128 	if (leaveValue != KErrNone) | 
|         |    129 	    { | 
|         |    130 	    xmlSecSetErrorFlag( leaveValue ); | 
|         |    131 	    return NULL; | 
|         |    132 	    }	 | 
|         |    133 	*(hd->hash)=hd->digest->Final(); | 
|         |    134 	return hd->hash->Ptr(); | 
|         |    135 } | 
|         |    136  | 
|         |    137 /* | 
|         |    138  * Read out the complete digest, this function implictly finalizes | 
|         |    139  * the hash. | 
|         |    140  */ | 
|         |    141 const byte * | 
|         |    142 sc_md_read (sc_md_hd_t hd, int /*algo*/) | 
|         |    143 { | 
|         |    144   const byte *ret; | 
|         |    145  | 
|         |    146   if (hd->hash) | 
|         |    147   { | 
|         |    148   	delete hd->hash; | 
|         |    149   	hd->hash = NULL; | 
|         |    150   }  | 
|         |    151   ret = md_read (hd); | 
|         |    152   return ret; | 
|         |    153 } | 
|         |    154  | 
|         |    155 void | 
|         |    156 sc_md_write (sc_md_hd_t hd, unsigned char *inbuf, size_t inlen) | 
|         |    157 { | 
|         |    158  | 
|         |    159   TPtrC8 inbufPtr(inbuf, inlen); | 
|         |    160   hd->digest->Update(inbufPtr); | 
|         |    161    | 
|         |    162 } | 
|         |    163  | 
|         |    164 void | 
|         |    165 sc_md_close (sc_md_hd_t hd) | 
|         |    166 { | 
|         |    167  | 
|         |    168   if (hd->digest) | 
|         |    169   { | 
|         |    170   	delete hd->digest; | 
|         |    171   	hd->digest = NULL;  	 | 
|         |    172   } | 
|         |    173  | 
|         |    174   if (hd->hash) | 
|         |    175   { | 
|         |    176   	delete hd->hash; | 
|         |    177   	hd->hash = NULL; | 
|         |    178   } | 
|         |    179    | 
|         |    180   free (hd); | 
|         |    181 } | 
|         |    182  | 
|         |    183 void | 
|         |    184 sc_md_final (sc_md_hd_t /*a*/) | 
|         |    185 { | 
|         |    186  	// Do nothing, sc_md_read will call final() | 
|         |    187 } | 
|         |    188  | 
|         |    189  | 
|         |    190 /* Set key for HMAC */ | 
|         |    191 int sc_md_setkey(sc_md_hd_t hd, unsigned char *buffer, size_t length) | 
|         |    192 { | 
|         |    193   TInt err; | 
|         |    194    | 
|         |    195   if (!hd || !buffer || length <=0) | 
|         |    196   	return KErrArgument; | 
|         |    197    | 
|         |    198   TPtrC8 keyPtr(buffer, length); | 
|         |    199     | 
|         |    200   if (hd->hmac)  | 
|         |    201   { | 
|         |    202   	// Initialize HMAC | 
|         |    203   	 TRAP(err, hd->digest = CHMAC::NewL(keyPtr, hd->digest)); | 
|         |    204   	 if ( err != KErrNone ) | 
|         |    205   	    { | 
|         |    206   	    xmlSecSetErrorFlag( err ); | 
|         |    207   	    } | 
|         |    208   }  		 		 | 
|         |    209    | 
|         |    210   return err; | 
|         |    211 } |