4 * This is free software; see Copyright file in the source
5 * distribution for preciese wording.
7 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
14 #include <gnutls/gnutls.h>
17 #include <xmlsec/xmlsec.h>
18 #include <xmlsec/xmltree.h>
19 #include <xmlsec/keys.h>
20 #include <xmlsec/transforms.h>
21 #include <xmlsec/errors.h>
23 #include <xmlsec/gnutls/app.h>
24 #include <xmlsec/gnutls/crypto.h>
27 #define XMLSEC_GNUTLS_MIN_HMAC_SIZE 80
28 #define XMLSEC_GNUTLS_MAX_HMAC_SIZE (128 * 8)
30 /**************************************************************************
34 *****************************************************************************/
35 static int g_xmlsec_gnutls_hmac_min_length = XMLSEC_GNUTLS_MIN_HMAC_SIZE;
38 * xmlSecGnuTLSHmacGetMinOutputLength:
40 * Gets the value of min HMAC length.
42 * Returns: the min HMAC output length
44 int xmlSecGnuTLSHmacGetMinOutputLength(void)
46 return g_xmlsec_gnutls_hmac_min_length;
50 * xmlSecGnuTLSHmacSetMinOutputLength:
51 * @min_length: the new min length
53 * Sets the min HMAC output length
55 void xmlSecGnuTLSHmacSetMinOutputLength(int min_length)
57 g_xmlsec_gnutls_hmac_min_length = min_length;
60 /**************************************************************************
62 * Internal GNUTLS HMAC CTX
64 *****************************************************************************/
65 typedef struct _xmlSecGnuTLSHmacCtx xmlSecGnuTLSHmacCtx, *xmlSecGnuTLSHmacCtxPtr;
66 struct _xmlSecGnuTLSHmacCtx {
69 xmlSecByte dgst[XMLSEC_GNUTLS_MAX_HMAC_SIZE / 8];
70 xmlSecSize dgstSize; /* dgst size in bits */
73 /******************************************************************************
77 * xmlSecGnuTLSHmacCtx is located after xmlSecTransform
79 *****************************************************************************/
80 #define xmlSecGnuTLSHmacGetCtx(transform) \
81 ((xmlSecGnuTLSHmacCtxPtr)(((xmlSecByte*)(transform)) + sizeof(xmlSecTransform)))
82 #define xmlSecGnuTLSHmacSize \
83 (sizeof(xmlSecTransform) + sizeof(xmlSecGnuTLSHmacCtx))
84 #define xmlSecGnuTLSHmacCheckId(transform) \
85 (xmlSecTransformCheckId((transform), xmlSecGnuTLSTransformHmacSha1Id) || \
86 xmlSecTransformCheckId((transform), xmlSecGnuTLSTransformHmacMd5Id) || \
87 xmlSecTransformCheckId((transform), xmlSecGnuTLSTransformHmacRipemd160Id))
89 static int xmlSecGnuTLSHmacInitialize (xmlSecTransformPtr transform);
90 static void xmlSecGnuTLSHmacFinalize (xmlSecTransformPtr transform);
91 static int xmlSecGnuTLSHmacNodeRead (xmlSecTransformPtr transform,
93 xmlSecTransformCtxPtr transformCtx);
94 static int xmlSecGnuTLSHmacSetKeyReq (xmlSecTransformPtr transform,
95 xmlSecKeyReqPtr keyReq);
96 static int xmlSecGnuTLSHmacSetKey (xmlSecTransformPtr transform,
98 static int xmlSecGnuTLSHmacVerify (xmlSecTransformPtr transform,
99 const xmlSecByte* data,
101 xmlSecTransformCtxPtr transformCtx);
102 static int xmlSecGnuTLSHmacExecute (xmlSecTransformPtr transform,
104 xmlSecTransformCtxPtr transformCtx);
107 xmlSecGnuTLSHmacInitialize(xmlSecTransformPtr transform) {
108 xmlSecGnuTLSHmacCtxPtr ctx;
109 #ifndef XMLSEC_GNUTLS_OLD
111 #endif /* XMLSEC_GNUTLS_OLD */
113 xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1);
114 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1);
116 ctx = xmlSecGnuTLSHmacGetCtx(transform);
117 xmlSecAssert2(ctx != NULL, -1);
119 memset(ctx, 0, sizeof(xmlSecGnuTLSHmacCtx));
120 if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformHmacSha1Id)) {
121 ctx->digest = GCRY_MD_SHA1;
122 } else if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformHmacMd5Id)) {
123 ctx->digest = GCRY_MD_MD5;
124 } else if(xmlSecTransformCheckId(transform, xmlSecGnuTLSTransformHmacRipemd160Id)) {
125 ctx->digest = GCRY_MD_RMD160;
127 xmlSecError(XMLSEC_ERRORS_HERE,
128 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
130 XMLSEC_ERRORS_R_INVALID_TRANSFORM,
131 XMLSEC_ERRORS_NO_MESSAGE);
135 #ifndef XMLSEC_GNUTLS_OLD
136 ret = gcry_md_open(&ctx->digestCtx, ctx->digest, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE); /* we are paranoid */
137 if(ret != GPG_ERR_NO_ERROR) {
138 #else /* XMLSEC_GNUTLS_OLD */
139 ctx->digestCtx = gcry_md_open(ctx->digest, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE); /* we are paranoid */
140 if(ctx->digestCtx == NULL) {
141 #endif /* XMLSEC_GNUTLS_OLD */
142 xmlSecError(XMLSEC_ERRORS_HERE,
143 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
145 XMLSEC_ERRORS_R_CRYPTO_FAILED,
146 XMLSEC_ERRORS_NO_MESSAGE);
154 xmlSecGnuTLSHmacFinalize(xmlSecTransformPtr transform) {
155 xmlSecGnuTLSHmacCtxPtr ctx;
157 xmlSecAssert(xmlSecGnuTLSHmacCheckId(transform));
158 xmlSecAssert(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize));
160 ctx = xmlSecGnuTLSHmacGetCtx(transform);
161 xmlSecAssert(ctx != NULL);
163 if(ctx->digestCtx != NULL) {
164 gcry_md_close(ctx->digestCtx);
166 memset(ctx, 0, sizeof(xmlSecGnuTLSHmacCtx));
170 * xmlSecGnuTLSHmacNodeRead:
172 * HMAC (http://www.w3.org/TR/xmldsig-core/#sec-HMAC):
174 * The HMAC algorithm (RFC2104 [HMAC]) takes the truncation length in bits
175 * as a parameter; if the parameter is not specified then all the bits of the
176 * hash are output. An example of an HMAC SignatureMethod element:
177 * <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1">
178 * <HMACOutputLength>128</HMACOutputLength>
183 * <simpleType name="HMACOutputLengthType">
184 * <restriction base="integer"/>
189 * <!ELEMENT HMACOutputLength (#PCDATA)>
192 xmlSecGnuTLSHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) {
193 xmlSecGnuTLSHmacCtxPtr ctx;
196 xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1);
197 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1);
198 xmlSecAssert2(node != NULL, -1);
199 xmlSecAssert2(transformCtx != NULL, -1);
201 ctx = xmlSecGnuTLSHmacGetCtx(transform);
202 xmlSecAssert2(ctx != NULL, -1);
204 cur = xmlSecGetNextElementNode(node->children);
205 if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) {
208 content = xmlNodeGetContent(cur);
209 if(content != NULL) {
210 ctx->dgstSize = atoi((char*)content);
214 /* Ensure that HMAC length is greater than min specified.
215 Otherwise, an attacker can set this lenght to 0 or very
218 if((int)ctx->dgstSize < xmlSecGnuTLSHmacGetMinOutputLength()) {
219 xmlSecError(XMLSEC_ERRORS_HERE,
220 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
221 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
222 XMLSEC_ERRORS_R_INVALID_NODE_ATTRIBUTE,
223 "HMAC output length is too small");
227 cur = xmlSecGetNextElementNode(cur->next);
231 xmlSecError(XMLSEC_ERRORS_HERE,
232 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
233 xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
234 XMLSEC_ERRORS_R_INVALID_NODE,
235 "no nodes expected");
243 xmlSecGnuTLSHmacSetKeyReq(xmlSecTransformPtr transform, xmlSecKeyReqPtr keyReq) {
244 xmlSecGnuTLSHmacCtxPtr ctx;
246 xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1);
247 xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
248 xmlSecAssert2(keyReq != NULL, -1);
249 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1);
251 ctx = xmlSecGnuTLSHmacGetCtx(transform);
252 xmlSecAssert2(ctx != NULL, -1);
254 keyReq->keyId = xmlSecGnuTLSKeyDataHmacId;
255 keyReq->keyType= xmlSecKeyDataTypeSymmetric;
256 if(transform->operation == xmlSecTransformOperationSign) {
257 keyReq->keyUsage = xmlSecKeyUsageSign;
259 keyReq->keyUsage = xmlSecKeyUsageVerify;
266 xmlSecGnuTLSHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
267 xmlSecGnuTLSHmacCtxPtr ctx;
268 xmlSecKeyDataPtr value;
269 xmlSecBufferPtr buffer;
272 xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1);
273 xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
274 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1);
275 xmlSecAssert2(key != NULL, -1);
277 ctx = xmlSecGnuTLSHmacGetCtx(transform);
278 xmlSecAssert2(ctx != NULL, -1);
279 xmlSecAssert2(ctx->digestCtx != NULL, -1);
281 value = xmlSecKeyGetValue(key);
282 xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecGnuTLSKeyDataHmacId), -1);
284 buffer = xmlSecKeyDataBinaryValueGetBuffer(value);
285 xmlSecAssert2(buffer != NULL, -1);
287 if(xmlSecBufferGetSize(buffer) == 0) {
288 xmlSecError(XMLSEC_ERRORS_HERE,
289 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
291 XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE,
296 ret = gcry_md_setkey(ctx->digestCtx, xmlSecBufferGetData(buffer),
297 xmlSecBufferGetSize(buffer));
299 xmlSecError(XMLSEC_ERRORS_HERE,
300 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
302 XMLSEC_ERRORS_R_CRYPTO_FAILED,
310 xmlSecGnuTLSHmacVerify(xmlSecTransformPtr transform,
311 const xmlSecByte* data, xmlSecSize dataSize,
312 xmlSecTransformCtxPtr transformCtx) {
313 static xmlSecByte last_byte_masks[] =
314 { 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
316 xmlSecGnuTLSHmacCtxPtr ctx;
319 xmlSecAssert2(xmlSecTransformIsValid(transform), -1);
320 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1);
321 xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1);
322 xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1);
323 xmlSecAssert2(data != NULL, -1);
324 xmlSecAssert2(transformCtx != NULL, -1);
326 ctx = xmlSecGnuTLSHmacGetCtx(transform);
327 xmlSecAssert2(ctx != NULL, -1);
328 xmlSecAssert2(ctx->digestCtx != NULL, -1);
329 xmlSecAssert2(ctx->dgstSize > 0, -1);
331 /* compare the digest size in bytes */
332 if(dataSize != ((ctx->dgstSize + 7) / 8)){
333 xmlSecError(XMLSEC_ERRORS_HERE,
334 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
336 XMLSEC_ERRORS_R_INVALID_SIZE,
338 dataSize, ((ctx->dgstSize + 7) / 8));
339 transform->status = xmlSecTransformStatusFail;
343 /* we check the last byte separatelly */
344 xmlSecAssert2(dataSize > 0, -1);
345 mask = last_byte_masks[ctx->dgstSize % 8];
346 if((ctx->dgst[dataSize - 1] & mask) != (data[dataSize - 1] & mask)) {
347 xmlSecError(XMLSEC_ERRORS_HERE,
348 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
350 XMLSEC_ERRORS_R_DATA_NOT_MATCH,
351 "data and digest do not match (last byte)");
352 transform->status = xmlSecTransformStatusFail;
356 /* now check the rest of the digest */
357 if((dataSize > 1) && (memcmp(ctx->dgst, data, dataSize - 1) != 0)) {
358 xmlSecError(XMLSEC_ERRORS_HERE,
359 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
361 XMLSEC_ERRORS_R_DATA_NOT_MATCH,
362 "data and digest do not match");
363 transform->status = xmlSecTransformStatusFail;
367 transform->status = xmlSecTransformStatusOk;
372 xmlSecGnuTLSHmacExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
373 xmlSecGnuTLSHmacCtxPtr ctx;
374 xmlSecBufferPtr in, out;
379 xmlSecAssert2(xmlSecGnuTLSHmacCheckId(transform), -1);
380 xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
381 xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGnuTLSHmacSize), -1);
382 xmlSecAssert2(transformCtx != NULL, -1);
384 ctx = xmlSecGnuTLSHmacGetCtx(transform);
385 xmlSecAssert2(ctx != NULL, -1);
386 xmlSecAssert2(ctx->digestCtx != NULL, -1);
388 in = &(transform->inBuf);
389 out = &(transform->outBuf);
391 if(transform->status == xmlSecTransformStatusNone) {
392 transform->status = xmlSecTransformStatusWorking;
395 if(transform->status == xmlSecTransformStatusWorking) {
398 inSize = xmlSecBufferGetSize(in);
400 gcry_md_write(ctx->digestCtx, xmlSecBufferGetData(in), inSize);
402 ret = xmlSecBufferRemoveHead(in, inSize);
404 xmlSecError(XMLSEC_ERRORS_HERE,
405 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
406 "xmlSecBufferRemoveHead",
407 XMLSEC_ERRORS_R_XMLSEC_FAILED,
413 /* get the final digest */
414 gcry_md_final(ctx->digestCtx);
415 dgst = gcry_md_read(ctx->digestCtx, ctx->digest);
417 xmlSecError(XMLSEC_ERRORS_HERE,
418 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
420 XMLSEC_ERRORS_R_CRYPTO_FAILED,
421 XMLSEC_ERRORS_NO_MESSAGE);
425 /* copy it to our internal buffer */
426 dgstSize = gcry_md_get_algo_dlen(ctx->digest);
427 xmlSecAssert2(dgstSize > 0, -1);
428 xmlSecAssert2(dgstSize <= sizeof(ctx->dgst), -1);
429 memcpy(ctx->dgst, dgst, dgstSize);
431 /* check/set the result digest size */
432 if(ctx->dgstSize == 0) {
433 ctx->dgstSize = dgstSize * 8; /* no dgst size specified, use all we have */
434 } else if(ctx->dgstSize <= 8 * dgstSize) {
435 dgstSize = ((ctx->dgstSize + 7) / 8); /* we need to truncate result digest */
437 xmlSecError(XMLSEC_ERRORS_HERE,
438 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
440 XMLSEC_ERRORS_R_INVALID_SIZE,
441 "result-bits=%d;required-bits=%d",
442 8 * dgstSize, ctx->dgstSize);
446 if(transform->operation == xmlSecTransformOperationSign) {
447 ret = xmlSecBufferAppend(out, ctx->dgst, dgstSize);
449 xmlSecError(XMLSEC_ERRORS_HERE,
450 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
451 "xmlSecBufferAppend",
452 XMLSEC_ERRORS_R_XMLSEC_FAILED,
453 "size=%d", dgstSize);
457 transform->status = xmlSecTransformStatusFinished;
459 } else if(transform->status == xmlSecTransformStatusFinished) {
460 /* the only way we can get here is if there is no input */
461 xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
463 xmlSecError(XMLSEC_ERRORS_HERE,
464 xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
466 XMLSEC_ERRORS_R_INVALID_STATUS,
467 "size=%d", transform->status);
477 static xmlSecTransformKlass xmlSecGnuTLSHmacSha1Klass = {
478 /* klass/object sizes */
479 sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
480 xmlSecGnuTLSHmacSize, /* xmlSecSize objSize */
482 xmlSecNameHmacSha1, /* const xmlChar* name; */
483 xmlSecHrefHmacSha1, /* const xmlChar *href; */
484 xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
486 xmlSecGnuTLSHmacInitialize, /* xmlSecTransformInitializeMethod initialize; */
487 xmlSecGnuTLSHmacFinalize, /* xmlSecTransformFinalizeMethod finalize; */
488 xmlSecGnuTLSHmacNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
489 NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
490 xmlSecGnuTLSHmacSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
491 xmlSecGnuTLSHmacSetKey, /* xmlSecTransformSetKeyMethod setKey; */
492 xmlSecGnuTLSHmacVerify, /* xmlSecTransformValidateMethod validate; */
493 xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
494 xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
495 xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
496 NULL, /* xmlSecTransformPushXmlMethod pushXml; */
497 NULL, /* xmlSecTransformPopXmlMethod popXml; */
498 xmlSecGnuTLSHmacExecute, /* xmlSecTransformExecuteMethod execute; */
500 NULL, /* void* reserved0; */
501 NULL, /* void* reserved1; */
505 * xmlSecGnuTLSTransformHmacSha1GetKlass:
507 * The HMAC-SHA1 transform klass.
509 * Returns: the HMAC-SHA1 transform klass.
512 xmlSecGnuTLSTransformHmacSha1GetKlass(void) {
513 return(&xmlSecGnuTLSHmacSha1Klass);
519 static xmlSecTransformKlass xmlSecGnuTLSHmacRipemd160Klass = {
520 /* klass/object sizes */
521 sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
522 xmlSecGnuTLSHmacSize, /* xmlSecSize objSize */
524 xmlSecNameHmacRipemd160, /* const xmlChar* name; */
525 xmlSecHrefHmacRipemd160, /* const xmlChar* href; */
526 xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
528 xmlSecGnuTLSHmacInitialize, /* xmlSecTransformInitializeMethod initialize; */
529 xmlSecGnuTLSHmacFinalize, /* xmlSecTransformFinalizeMethod finalize; */
530 xmlSecGnuTLSHmacNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
531 NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
532 xmlSecGnuTLSHmacSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
533 xmlSecGnuTLSHmacSetKey, /* xmlSecTransformSetKeyMethod setKey; */
534 xmlSecGnuTLSHmacVerify, /* xmlSecTransformValidateMethod validate; */
535 xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
536 xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
537 xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
538 NULL, /* xmlSecTransformPushXmlMethod pushXml; */
539 NULL, /* xmlSecTransformPopXmlMethod popXml; */
540 xmlSecGnuTLSHmacExecute, /* xmlSecTransformExecuteMethod execute; */
542 NULL, /* void* reserved0; */
543 NULL, /* void* reserved1; */
547 * xmlSecGnuTLSTransformHmacRipemd160GetKlass:
549 * The HMAC-RIPEMD160 transform klass.
551 * Returns: the HMAC-RIPEMD160 transform klass.
554 xmlSecGnuTLSTransformHmacRipemd160GetKlass(void) {
555 return(&xmlSecGnuTLSHmacRipemd160Klass);
561 static xmlSecTransformKlass xmlSecGnuTLSHmacMd5Klass = {
562 /* klass/object sizes */
563 sizeof(xmlSecTransformKlass), /* xmlSecSize klassSize */
564 xmlSecGnuTLSHmacSize, /* xmlSecSize objSize */
566 xmlSecNameHmacMd5, /* const xmlChar* name; */
567 xmlSecHrefHmacMd5, /* const xmlChar* href; */
568 xmlSecTransformUsageSignatureMethod, /* xmlSecTransformUsage usage; */
570 xmlSecGnuTLSHmacInitialize, /* xmlSecTransformInitializeMethod initialize; */
571 xmlSecGnuTLSHmacFinalize, /* xmlSecTransformFinalizeMethod finalize; */
572 xmlSecGnuTLSHmacNodeRead, /* xmlSecTransformNodeReadMethod readNode; */
573 NULL, /* xmlSecTransformNodeWriteMethod writeNode; */
574 xmlSecGnuTLSHmacSetKeyReq, /* xmlSecTransformSetKeyReqMethod setKeyReq; */
575 xmlSecGnuTLSHmacSetKey, /* xmlSecTransformSetKeyMethod setKey; */
576 xmlSecGnuTLSHmacVerify, /* xmlSecTransformValidateMethod validate; */
577 xmlSecTransformDefaultGetDataType, /* xmlSecTransformGetDataTypeMethod getDataType; */
578 xmlSecTransformDefaultPushBin, /* xmlSecTransformPushBinMethod pushBin; */
579 xmlSecTransformDefaultPopBin, /* xmlSecTransformPopBinMethod popBin; */
580 NULL, /* xmlSecTransformPushXmlMethod pushXml; */
581 NULL, /* xmlSecTransformPopXmlMethod popXml; */
582 xmlSecGnuTLSHmacExecute, /* xmlSecTransformExecuteMethod execute; */
584 NULL, /* void* reserved0; */
585 NULL, /* void* reserved1; */
589 * xmlSecGnuTLSTransformHmacMd5GetKlass:
591 * The HMAC-MD5 transform klass.
593 * Returns: the HMAC-MD5 transform klass.
596 xmlSecGnuTLSTransformHmacMd5GetKlass(void) {
597 return(&xmlSecGnuTLSHmacMd5Klass);
601 #endif /* XMLSEC_NO_HMAC */