/**
* 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.
* Portion Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
*/
#include "xmlsec_globals.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdapis/libxml2/libxml2_tree.h>
#include <stdapis/libxml2/libxml2_globals.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.
*/
EXPORT_C
xmlSecBnPtr
xmlSecBnCreate(xmlSecSize size) {
return(xmlSecBufferCreate(size));
}
/**
* xmlSecBnDestroy:
* @bn: the pointer to BN.
*
* Destroys @bn object created with @xmlSecBnCreate function.
*/
EXPORT_C
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.
*/
EXPORT_C
int
xmlSecBnInitialize(xmlSecBnPtr bn, xmlSecSize size) {
return(xmlSecBufferInitialize(bn, size));
}
/**
* xmlSecBnFinalize:
* @bn: the pointer to BN.
*
* Destroys @bn object created with @xmlSecBnInitialize function.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
xmlSecSize
xmlSecBnGetSize(xmlSecBnPtr bn) {
return(xmlSecBufferGetSize(bn));
}
/**
* xmlSecBnZero:
* @bn: the pointer to BN.
*
* Sets the value of @bn to zero.
*/
EXPORT_C
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.
*/
EXPORT_C
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)/sizeof(xmlSecBnLookupTable[0])), -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.
*/
EXPORT_C
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);
}
if(nn >=(sizeof(xmlSecBnRevLookupTable)/sizeof(xmlSecBnRevLookupTable[0])))
{
xmlFree(res);
return (NULL);
}
res[i] = xmlSecBnRevLookupTable[nn];
}
if(i >=len)
{
xmlFree(res);
return (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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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.
*/
EXPORT_C
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, XMLSEC_BASE64_LINESIZE);
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.
*/
EXPORT_C
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);
}