diff options
Diffstat (limited to 'src/bn.c')
-rw-r--r-- | src/bn.c | 1060 |
1 files changed, 1060 insertions, 0 deletions
diff --git a/src/bn.c b/src/bn.c new file mode 100644 index 00000000..06a31d5b --- /dev/null +++ b/src/bn.c @@ -0,0 +1,1060 @@ +/** + * XML Security Library (http://www.aleksey.com/xmlsec). + * + * Big Numbers. + * + * This is free software; see Copyright file in the source + * distribution for preciese wording. + * + * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com> + * Copyright (C) 2003 Cordys R&D BV, All rights reserved. + */ +#include "globals.h" + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include <libxml/tree.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/xmltree.h> +#include <xmlsec/base64.h> +#include <xmlsec/bn.h> +#include <xmlsec/errors.h> + +/* table for converting hex digits back to bytes */ +static const int xmlSecBnLookupTable[] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const char xmlSecBnRevLookupTable[] = +{ + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/***************************************************************************** + * + * xmlSecBn + * + ****************************************************************************/ +/** + * xmlSecBnCreate: + * @size: the initial allocated BN size. + * + * Creates a new BN object. Caller is responsible for destroying it + * by calling @xmlSecBnDestroy function. + * + * Returns: the newly BN or a NULL if an error occurs. + */ +xmlSecBnPtr +xmlSecBnCreate(xmlSecSize size) { + return(xmlSecBufferCreate(size)); +} + +/** + * xmlSecBnDestroy: + * @bn: the pointer to BN. + * + * Destroys @bn object created with @xmlSecBnCreate function. + */ +void +xmlSecBnDestroy(xmlSecBnPtr bn) { + xmlSecBufferDestroy(bn); +} + +/** + * xmlSecBnInitialize: + * @bn: the pointer to BN. + * @size: the initial allocated BN size. + * + * Initializes a BN object. Caller is responsible for destroying it + * by calling @xmlSecBnFinalize function. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnInitialize(xmlSecBnPtr bn, xmlSecSize size) { + return(xmlSecBufferInitialize(bn, size)); +} + +/** + * xmlSecBnFinalize: + * @bn: the pointer to BN. + * + * Destroys @bn object created with @xmlSecBnInitialize function. + */ +void +xmlSecBnFinalize(xmlSecBnPtr bn) { + xmlSecBufferFinalize(bn); +} + +/** + * xmlSecBnGetData: + * @bn: the pointer to BN. + * + * Gets pointer to the binary @bn representation. + * + * Returns: pointer to binary BN data or NULL if an error occurs. + */ +xmlSecByte* +xmlSecBnGetData(xmlSecBnPtr bn) { + return(xmlSecBufferGetData(bn)); +} + +/** + * xmlSecBnSetData: + * @bn: the pointer to BN. + * @data: the pointer to new BN binary data. + * @size: the size of new BN data. + * + * Sets the value of @bn to @data. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnSetData(xmlSecBnPtr bn, const xmlSecByte* data, xmlSecSize size) { + return(xmlSecBufferSetData(bn, data, size)); +} + +/** + * xmlSecBnGetSize: + * @bn: the pointer to BN. + * + * Gets the size of binary data in @bn. + * + * Returns: the size of binary data. + */ +xmlSecSize +xmlSecBnGetSize(xmlSecBnPtr bn) { + return(xmlSecBufferGetSize(bn)); +} + +/** + * xmlSecBnZero: + * @bn: the pointer to BN. + * + * Sets the value of @bn to zero. + */ +void +xmlSecBnZero(xmlSecBnPtr bn) { + xmlSecBufferEmpty(bn); +} + +/** + * xmlSecBnFromString: + * @bn: the pointer to BN. + * @str: the string with BN. + * @base: the base for @str. + * + * Reads @bn from string @str assuming it has base @base. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnFromString(xmlSecBnPtr bn, const xmlChar* str, xmlSecSize base) { + xmlSecSize i, len, size; + xmlSecByte ch; + xmlSecByte* data; + int positive; + int nn; + int ret; + + xmlSecAssert2(bn != NULL, -1); + xmlSecAssert2(str != NULL, -1); + xmlSecAssert2(base > 1, -1); + xmlSecAssert2(base <= sizeof(xmlSecBnRevLookupTable), -1); + + /* trivial case */ + len = xmlStrlen(str); + if(len == 0) { + return(0); + } + + /* The result size could not exceed the input string length + * because each char fits inside a byte in all cases :) + * In truth, it would be likely less than 1/2 input string length + * because each byte is represented by 2 chars. If needed, + * buffer size would be increased by Mul/Add functions. + * Finally, we can add one byte for 00 or 10 prefix. + */ + ret = xmlSecBufferSetMaxSize(bn, xmlSecBufferGetSize(bn) + len / 2 + 1 + 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnRevLookupTable", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", len / 2 + 1); + return (-1); + } + + /* figure out if it is positive or negative number */ + positive = 1; + i = 0; + while(i < len) { + ch = str[i++]; + + /* skip spaces */ + if(isspace(ch)) { + continue; + } + + /* check if it is + or - */ + if(ch == '+') { + positive = 1; + break; + } else if(ch == '-') { + positive = 0; + break; + } + + /* otherwise, it must be start of the number */ + nn = xmlSecBnLookupTable[ch]; + if((nn >= 0) && ((xmlSecSize)nn < base)) { + xmlSecAssert2(i > 0, -1); + + /* no sign, positive by default */ + positive = 1; + --i; /* make sure that we will look at this character in next loop */ + break; + } else { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_INVALID_DATA, + "char=%c;base=%d", + ch, base); + return (-1); + } + } + + /* now parse the number itself */ + while(i < len) { + ch = str[i++]; + if(isspace(ch)) { + continue; + } + + xmlSecAssert2(ch <= sizeof(xmlSecBnLookupTable), -1); + nn = xmlSecBnLookupTable[ch]; + if((nn < 0) || ((xmlSecSize)nn > base)) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_INVALID_DATA, + "char=%c;base=%d", + ch, base); + return (-1); + } + + ret = xmlSecBnMul(bn, base); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnMul", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "base=%d", base); + return (-1); + } + + ret = xmlSecBnAdd(bn, nn); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnAdd", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "base=%d", base); + return (-1); +} + } + + /* check if we need to add 00 prefix, do this for empty bn too */ + data = xmlSecBufferGetData(bn); + size = xmlSecBufferGetSize(bn); + if(((size > 0) && (data[0] > 127)) || (size == 0)) { + ch = 0; + ret = xmlSecBufferPrepend(bn, &ch, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferPrepend", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "base=%d", base); + return (-1); + } + } + + /* do 2's compliment and add 1 to represent negative value */ + if(positive == 0) { + data = xmlSecBufferGetData(bn); + size = xmlSecBufferGetSize(bn); + for(i = 0; i < size; ++i) { + data[i] ^= 0xFF; + } + + ret = xmlSecBnAdd(bn, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnAdd", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "base=%d", base); + return (-1); + } + } + + return(0); +} + +/** + * xmlSecBnToString: + * @bn: the pointer to BN. + * @base: the base for returned string. + * + * Writes @bn to string with base @base. Caller is responsible for + * freeing returned string with @xmlFree. + * + * Returns: the string represenataion if BN or a NULL if an error occurs. + */ +xmlChar* +xmlSecBnToString(xmlSecBnPtr bn, xmlSecSize base) { + xmlSecBn bn2; + int positive = 1; + xmlChar* res; + xmlSecSize i, len, size; + xmlSecByte* data; + int ret; + int nn; + xmlChar ch; + + xmlSecAssert2(bn != NULL, NULL); + xmlSecAssert2(base > 1, NULL); + xmlSecAssert2(base <= sizeof(xmlSecBnRevLookupTable), NULL); + + + /* copy bn */ + data = xmlSecBufferGetData(bn); + size = xmlSecBufferGetSize(bn); + ret = xmlSecBnInitialize(&bn2, size); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnCreate", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", size); + return (NULL); + } + + ret = xmlSecBnSetData(&bn2, data, size); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnSetData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", size); + xmlSecBnFinalize(&bn2); + return (NULL); + } + + /* check if it is a negative number or not */ + data = xmlSecBufferGetData(&bn2); + size = xmlSecBufferGetSize(&bn2); + if((size > 0) && (data[0] > 127)) { + /* subtract 1 and do 2's compliment */ + ret = xmlSecBnAdd(&bn2, -1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnAdd", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", size); + xmlSecBnFinalize(&bn2); + return (NULL); + } + for(i = 0; i < size; ++i) { + data[i] ^= 0xFF; + } + + positive = 0; + } else { + positive = 1; + } + + /* Result string len is + * len = log base (256) * <bn size> + * Since the smallest base == 2 then we can get away with + * len = 8 * <bn size> + */ + len = 8 * size + 1 + 1; + res = (xmlChar*)xmlMalloc(len + 1); + if(res == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + "len=%d", len); + xmlSecBnFinalize(&bn2); + return (NULL); + } + memset(res, 0, len + 1); + + for(i = 0; (xmlSecBufferGetSize(&bn2) > 0) && (i < len); i++) { + if(xmlSecBnDiv(&bn2, base, &nn) < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnDiv", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "base=%d", base); + xmlFree(res); + xmlSecBnFinalize(&bn2); + return (NULL); + } + xmlSecAssert2((size_t)nn < sizeof(xmlSecBnRevLookupTable), NULL); + res[i] = xmlSecBnRevLookupTable[nn]; + } + xmlSecAssert2(i < len, NULL); + + /* we might have '0' at the beggining, remove it but keep one zero */ + for(len = i; (len > 1) && (res[len - 1] == '0'); len--); + res[len] = '\0'; + + /* add "-" for negative numbers */ + if(positive == 0) { + res[len] = '-'; + res[++len] = '\0'; + } + + /* swap the string because we wrote it in reverse order */ + for(i = 0; i < len / 2; i++) { + ch = res[i]; + res[i] = res[len - i - 1]; + res[len - i - 1] = ch; + } + + xmlSecBnFinalize(&bn2); + return(res); +} + +/** + * xmlSecBnFromHexString: + * @bn: the pointer to BN. + * @str: the string with BN. + * + * Reads @bn from hex string @str. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnFromHexString(xmlSecBnPtr bn, const xmlChar* str) { + return(xmlSecBnFromString(bn, str, 16)); +} + +/** + * xmlSecBnToHexString: + * @bn: the pointer to BN. + * + * Writes @bn to hex string. Caller is responsible for + * freeing returned string with @xmlFree. + * + * Returns: the string represenataion if BN or a NULL if an error occurs. + */ +xmlChar* +xmlSecBnToHexString(xmlSecBnPtr bn) { + return(xmlSecBnToString(bn, 16)); +} + +/** + * xmlSecBnFromDecString: + * @bn: the pointer to BN. + * @str: the string with BN. + * + * Reads @bn from decimal string @str. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnFromDecString(xmlSecBnPtr bn, const xmlChar* str) { + return(xmlSecBnFromString(bn, str, 10)); +} + +/** + * xmlSecBnToDecString: + * @bn: the pointer to BN. + * + * Writes @bn to decimal string. Caller is responsible for + * freeing returned string with @xmlFree. + * + * Returns: the string represenataion if BN or a NULL if an error occurs. + */ +xmlChar* +xmlSecBnToDecString(xmlSecBnPtr bn) { + return(xmlSecBnToString(bn, 10)); +} + +/** + * xmlSecBnMul: + * @bn: the pointer to BN. + * @multiplier: the multiplier. + * + * Multiplies @bn with @multiplier. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnMul(xmlSecBnPtr bn, int multiplier) { + xmlSecByte* data; + int over; + xmlSecSize i; + xmlSecByte ch; + int ret; + + xmlSecAssert2(bn != NULL, -1); + xmlSecAssert2(multiplier > 0, -1); + + if(multiplier == 1) { + return(0); + } + + data = xmlSecBufferGetData(bn); + i = xmlSecBufferGetSize(bn); + over = 0; + while(i > 0) { + xmlSecAssert2(data != NULL, -1); + + over = over + multiplier * data[--i]; + data[i] = over % 256; + over = over / 256; + } + + while(over > 0) { + ch = over % 256; + over = over / 256; + + ret = xmlSecBufferPrepend(bn, &ch, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferPrepend", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=1"); + return (-1); + } + } + + return(0); +} + +/** + * xmlSecBnDiv: + * @bn: the pointer to BN. + * @divider: the divider + * @mod: the pointer for modulus result. + * + * Divides @bn by @divider and places modulus into @mod. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnDiv(xmlSecBnPtr bn, int divider, int* mod) { + int over; + xmlSecSize i, size; + xmlSecByte* data; + int ret; + + xmlSecAssert2(bn != NULL, -1); + xmlSecAssert2(divider > 0, -1); + xmlSecAssert2(mod != NULL, -1); + + if(divider == 1) { + return(0); + } + + data = xmlSecBufferGetData(bn); + size = xmlSecBufferGetSize(bn); + for(over = 0, i = 0; i < size; i++) { + xmlSecAssert2(data != NULL, -1); + + over = over * 256 + data[i]; + data[i] = over / divider; + over = over % divider; + } + (*mod) = over; + + /* remove leading zeros */ + for(i = 0; i < size; i++) { + xmlSecAssert2(data != NULL, -1); + + if(data[i] != 0) { + break; + } + } + if(i > 0) { + ret = xmlSecBufferRemoveHead(bn, i); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferRemoveHead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=%d", i); + return (-1); + } + } + return(0); +} + +/** + * xmlSecBnAdd: + * @bn: the pointer to BN. + * @delta: the delta. + * + * Adds @delta to @bn. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnAdd(xmlSecBnPtr bn, int delta) { + int over, tmp; + xmlSecByte* data; + xmlSecSize i; + xmlSecByte ch; + int ret; + + xmlSecAssert2(bn != NULL, -1); + + if(delta == 0) { + return(0); + } + + data = xmlSecBufferGetData(bn); + if(delta > 0) { + for(over = delta, i = xmlSecBufferGetSize(bn); (i > 0) && (over > 0) ;) { + xmlSecAssert2(data != NULL, -1); + + tmp = data[--i]; + over += tmp; + data[i] = over % 256; + over = over / 256; + } + + while(over > 0) { + ch = over % 256; + over = over / 256; + + ret = xmlSecBufferPrepend(bn, &ch, 1); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferPrepend", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + "size=1"); + return (-1); + } + } + } else { + for(over = -delta, i = xmlSecBufferGetSize(bn); (i > 0) && (over > 0);) { + xmlSecAssert2(data != NULL, -1); + + tmp = data[--i]; + if(tmp < over) { + data[i] = 0; + over = (over - tmp) / 256; + } else { + data[i] = tmp - over; + over = 0; + } + } + } + return(0); +} + +/** + * xmlSecBnReverse: + * @bn: the pointer to BN. + * + * Reverses bytes order in @bn. + * + * Returns: 0 on success or a negative value if an error occurs. + */ +int +xmlSecBnReverse(xmlSecBnPtr bn) { + xmlSecByte* data; + xmlSecSize i, j, size; + xmlSecByte ch; + + xmlSecAssert2(bn != NULL, -1); + + data = xmlSecBufferGetData(bn); + size = xmlSecBufferGetSize(bn); + for(i = 0, j = size - 1; i < size / 2; ++i, --j) { + xmlSecAssert2(data != NULL, -1); + + ch = data[i]; + data[i] = data[j]; + data[j] = ch; + } + + return(0); +} + +/** + * xmlSecBnCompare: + * @bn: the pointer to BN. + * @data: the data to compare BN to. + * @dataSize: the @data size. + * + * Compares the @bn with @data. + * + * Returns: 0 if data is equal, negative value if @bn is less or positive value if @bn + * is greater than @data. + */ +int +xmlSecBnCompare(xmlSecBnPtr bn, const xmlSecByte* data, xmlSecSize dataSize) { + xmlSecByte* bnData; + xmlSecSize bnSize; + + xmlSecAssert2(bn != NULL, -1); + + bnData = xmlSecBnGetData(bn); + bnSize = xmlSecBnGetSize(bn); + + /* skip zeros in the beggining */ + while((dataSize > 0) && (data != 0) && (data[0] == 0)) { + ++data; + --dataSize; + } + while((bnSize > 0) && (bnData != 0) && (bnData[0] == 0)) { + ++bnData; + --bnSize; + } + + if(((bnData == NULL) || (bnSize == 0)) && ((data == NULL) || (dataSize == 0))) { + return(0); + } else if((bnData == NULL) || (bnSize == 0)) { + return(-1); + } else if((data == NULL) || (dataSize == 0)) { + return(1); + } else if(bnSize < dataSize) { + return(-1); + } else if(bnSize > dataSize) { + return(-1); + } + + xmlSecAssert2(bnData != NULL, -1); + xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(bnSize == dataSize, -1); + + return(memcmp(bnData, data, dataSize)); +} + +/** + * xmlSecBnCompareReverse: + * @bn: the pointer to BN. + * @data: the data to compare BN to. + * @dataSize: the @data size. + * + * Compares the @bn with reverse @data. + * + * Returns: 0 if data is equal, negative value if @bn is less or positive value if @bn + * is greater than @data. + */ +int +xmlSecBnCompareReverse(xmlSecBnPtr bn, const xmlSecByte* data, xmlSecSize dataSize) { + xmlSecByte* bnData; + xmlSecSize bnSize; + xmlSecSize i, j; + + xmlSecAssert2(bn != NULL, -1); + + bnData = xmlSecBnGetData(bn); + bnSize = xmlSecBnGetSize(bn); + + /* skip zeros in the beggining */ + while((dataSize > 0) && (data != 0) && (data[dataSize - 1] == 0)) { + --dataSize; + } + while((bnSize > 0) && (bnData != 0) && (bnData[0] == 0)) { + ++bnData; + --bnSize; + } + + if(((bnData == NULL) || (bnSize == 0)) && ((data == NULL) || (dataSize == 0))) { + return(0); + } else if((bnData == NULL) || (bnSize == 0)) { + return(-1); + } else if((data == NULL) || (dataSize == 0)) { + return(1); + } else if(bnSize < dataSize) { + return(-1); + } else if(bnSize > dataSize) { + return(-1); + } + + xmlSecAssert2(bnData != NULL, -1); + xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(bnSize == dataSize, -1); + for(i = 0, j = dataSize - 1; i < dataSize; ++i, --j) { + if(bnData[i] < data[j]) { + return(-1); + } else if(data[j] < bnData[i]) { + return(1); + } + } + + return(0); +} + +/** + * xmlSecBnGetNodeValue: + * @bn: the pointer to BN. + * @cur: the poitner to an XML node. + * @format: the BN format. + * @reverse: if set then reverse read buffer after reading. + * + * Converts the node content from @format to @bn. + * + * Returns: 0 on success and a negative values if an error occurs. + */ +int +xmlSecBnGetNodeValue(xmlSecBnPtr bn, xmlNodePtr cur, xmlSecBnFormat format, int reverse) { + xmlChar* content; + int ret; + + xmlSecAssert2(bn != NULL, -1); + xmlSecAssert2(cur != NULL, -1); + + switch(format) { + case xmlSecBnBase64: + ret = xmlSecBufferBase64NodeContentRead(bn, cur); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferBase64NodeContentRead", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + break; + case xmlSecBnHex: + content = xmlNodeGetContent(cur); + if(content == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlNodeGetContent", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecBnFromHexString(bn, content); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnFromHexString", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(content); + return(-1); + } + xmlFree(content); + break; + case xmlSecBnDec: + content = xmlNodeGetContent(cur); + if(content == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlNodeGetContent", + XMLSEC_ERRORS_R_XML_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + ret = xmlSecBnFromDecString(bn, content); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnFromDecString", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(content); + return(-1); + } + xmlFree(content); + break; + } + + if(reverse != 0) { + ret = xmlSecBnReverse(bn); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnReverse", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + return(0); +} + +/** + * xmlSecBnSetNodeValue: + * @bn: the pointer to BN. + * @cur: the poitner to an XML node. + * @format: the BN format. + * @reverse: the flag that indicates whether to reverse the buffer before writing. + * @addLineBreaks: the flag; it is equal to 1 then linebreaks will be added before and after new buffer content. + * + * Converts the @bn and sets it to node content. + * + * Returns: 0 on success and a negative values if an error occurs. + */ +int +xmlSecBnSetNodeValue(xmlSecBnPtr bn, xmlNodePtr cur, xmlSecBnFormat format, int reverse, int addLineBreaks) { + xmlChar* content; + int ret; + + xmlSecAssert2(bn != NULL, -1); + xmlSecAssert2(cur != NULL, -1); + + if(reverse != 0) { + ret = xmlSecBnReverse(bn); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnReverse", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + } + + if(addLineBreaks) { + xmlNodeAddContent(cur, xmlSecStringCR); + } + + switch(format) { + case xmlSecBnBase64: + ret = xmlSecBufferBase64NodeContentWrite(bn, cur, xmlSecBase64GetDefaultLineSize()); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBufferBase64NodeContentWrite", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + break; + case xmlSecBnHex: + content = xmlSecBnToHexString(bn); + if(content == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnToHexString", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(content); + return(-1); + } + xmlNodeSetContent(cur, content); + xmlFree(content); + break; + case xmlSecBnDec: + content = xmlSecBnToDecString(bn); + if(content == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnToDecString", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlFree(content); + return(-1); + } + xmlNodeSetContent(cur, content); + xmlFree(content); + break; + } + + if(addLineBreaks) { + xmlNodeAddContent(cur, xmlSecStringCR); + } + + return(0); +} + +/** + * xmlSecBnBlobSetNodeValue: + * @data: the pointer to BN blob. + * @dataSize: the size of BN blob. + * @cur: the poitner to an XML node. + * @format: the BN format. + * @reverse: the flag that indicates whether to reverse the buffer before writing. + * @addLineBreaks: if the flag is equal to 1 then + * linebreaks will be added before and after + * new buffer content. + * + * Converts the @blob and sets it to node content. + * + * Returns: 0 on success and a negative values if an error occurs. + */ +int +xmlSecBnBlobSetNodeValue(const xmlSecByte* data, xmlSecSize dataSize, + xmlNodePtr cur, xmlSecBnFormat format, int reverse, + int addLineBreaks) { + xmlSecBn bn; + int ret; + + xmlSecAssert2(data != NULL, -1); + xmlSecAssert2(cur != NULL, -1); + + ret = xmlSecBnInitialize(&bn, dataSize); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnInitialize", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + return(-1); + } + + ret = xmlSecBnSetData(&bn, data, dataSize); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnSetData", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecBnFinalize(&bn); + return(-1); + } + + ret = xmlSecBnSetNodeValue(&bn, cur, format, reverse, addLineBreaks); + if(ret < 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlSecBnSetNodeValue", + XMLSEC_ERRORS_R_XMLSEC_FAILED, + XMLSEC_ERRORS_NO_MESSAGE); + xmlSecBnFinalize(&bn); + return(-1); + } + + xmlSecBnFinalize(&bn); + return(0); +} + + |