|
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 } |