LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/xmlsec/src - bn.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 375 0.0 %
Date: 2012-12-17 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /** 
       2             :  * XML Security Library (http://www.aleksey.com/xmlsec).
       3             :  *
       4             :  * Big Numbers.
       5             :  *
       6             :  * This is free software; see Copyright file in the source
       7             :  * distribution for preciese wording.
       8             :  * 
       9             :  * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
      10             :  * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
      11             :  */
      12             : #include "globals.h"
      13             : 
      14             : #include <stdlib.h>
      15             : #include <string.h>
      16             : #include <ctype.h>
      17             :  
      18             : #include <libxml/tree.h>
      19             : 
      20             : #include <xmlsec/xmlsec.h>
      21             : #include <xmlsec/xmltree.h>
      22             : #include <xmlsec/base64.h>
      23             : #include <xmlsec/bn.h>
      24             : #include <xmlsec/errors.h>
      25             : 
      26             : /* table for converting hex digits back to bytes */
      27             : static const int xmlSecBnLookupTable[] =
      28             : {
      29             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      30             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      31             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      32             :      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
      33             :     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      34             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      35             :     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      36             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      37             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      38             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      39             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      40             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      41             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      42             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      43             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
      44             :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
      45             : };
      46             : 
      47             : static const char xmlSecBnRevLookupTable[] = 
      48             : { 
      49             :     '0', '1', '2', '3', '4', '5', '6', '7', 
      50             :     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
      51             : };
      52             : 
      53             : /*****************************************************************************
      54             :  *
      55             :  * xmlSecBn
      56             :  *
      57             :  ****************************************************************************/
      58             : /**
      59             :  * xmlSecBnCreate:
      60             :  * @size:       the initial allocated BN size.
      61             :  *
      62             :  * Creates a new BN object. Caller is responsible for destroying it
      63             :  * by calling @xmlSecBnDestroy function.
      64             :  *
      65             :  * Returns: the newly BN or a NULL if an error occurs.
      66             :  */
      67             : xmlSecBnPtr 
      68           0 : xmlSecBnCreate(xmlSecSize size) {
      69           0 :     return(xmlSecBufferCreate(size));
      70             : }
      71             : 
      72             : /**
      73             :  * xmlSecBnDestroy:
      74             :  * @bn:         the pointer to BN.
      75             :  *
      76             :  * Destroys @bn object created with @xmlSecBnCreate function.
      77             :  */
      78             : void 
      79           0 : xmlSecBnDestroy(xmlSecBnPtr bn) {
      80           0 :     xmlSecBufferDestroy(bn);
      81           0 : }
      82             : 
      83             : /**
      84             :  * xmlSecBnInitialize:
      85             :  * @bn:         the pointer to BN.
      86             :  * @size:       the initial allocated BN size.
      87             :  *
      88             :  * Initializes a BN object. Caller is responsible for destroying it
      89             :  * by calling @xmlSecBnFinalize function.
      90             :  *
      91             :  * Returns: 0 on success or a negative value if an error occurs.
      92             :  */
      93             : int 
      94           0 : xmlSecBnInitialize(xmlSecBnPtr bn, xmlSecSize size) {
      95           0 :     return(xmlSecBufferInitialize(bn, size));
      96             : }
      97             : 
      98             : /**
      99             :  * xmlSecBnFinalize:
     100             :  * @bn:         the pointer to BN.
     101             :  *
     102             :  * Destroys @bn object created with @xmlSecBnInitialize function.
     103             :  */
     104             : void 
     105           0 : xmlSecBnFinalize(xmlSecBnPtr bn) {
     106           0 :     xmlSecBufferFinalize(bn);
     107           0 : }
     108             : 
     109             : /**
     110             :  * xmlSecBnGetData:
     111             :  * @bn:         the pointer to BN.
     112             :  *
     113             :  * Gets pointer to the binary @bn representation.
     114             :  * 
     115             :  * Returns: pointer to binary BN data or NULL if an error occurs.
     116             :  */
     117             : xmlSecByte* 
     118           0 : xmlSecBnGetData(xmlSecBnPtr bn) {
     119           0 :     return(xmlSecBufferGetData(bn));
     120             : }
     121             : 
     122             : /**
     123             :  * xmlSecBnSetData:
     124             :  * @bn:         the pointer to BN.
     125             :  * @data:       the pointer to new BN binary data.
     126             :  * @size:       the size of new BN data.
     127             :  *
     128             :  * Sets the value of @bn to @data.
     129             :  *
     130             :  * Returns: 0 on success or a negative value if an error occurs.
     131             :  */
     132             : int 
     133           0 : xmlSecBnSetData(xmlSecBnPtr bn, const xmlSecByte* data, xmlSecSize size) {
     134           0 :     return(xmlSecBufferSetData(bn, data, size));
     135             : }
     136             : 
     137             : /**
     138             :  * xmlSecBnGetSize:
     139             :  * @bn:         the pointer to BN.
     140             :  *
     141             :  * Gets the size of binary data in @bn.
     142             :  *
     143             :  * Returns: the size of binary data.
     144             :  */
     145             : xmlSecSize 
     146           0 : xmlSecBnGetSize(xmlSecBnPtr bn) {
     147           0 :     return(xmlSecBufferGetSize(bn));
     148             : }
     149             : 
     150             : /**
     151             :  * xmlSecBnZero:
     152             :  * @bn:         the pointer to BN.
     153             :  *
     154             :  * Sets the value of @bn to zero.
     155             :  */
     156             : void 
     157           0 : xmlSecBnZero(xmlSecBnPtr bn) {
     158           0 :     xmlSecBufferEmpty(bn);
     159           0 : }
     160             : 
     161             : /**
     162             :  * xmlSecBnFromString:
     163             :  * @bn:         the pointer to BN.
     164             :  * @str:        the string with BN.
     165             :  * @base:       the base for @str.
     166             :  *
     167             :  * Reads @bn from string @str assuming it has base @base.
     168             :  *
     169             :  * Returns: 0 on success or a negative value if an error occurs.
     170             :  */
     171             : int 
     172           0 : xmlSecBnFromString(xmlSecBnPtr bn, const xmlChar* str, xmlSecSize base) {
     173             :     xmlSecSize i, len, size;
     174             :     xmlSecByte ch;
     175             :     xmlSecByte* data;
     176             :     int positive;
     177             :     int nn;
     178             :     int ret;
     179             : 
     180           0 :     xmlSecAssert2(bn != NULL, -1);
     181           0 :     xmlSecAssert2(str != NULL, -1);
     182           0 :     xmlSecAssert2(base > 1, -1);
     183           0 :     xmlSecAssert2(base <= sizeof(xmlSecBnRevLookupTable), -1);
     184             : 
     185             :     /* trivial case */
     186           0 :     len = xmlStrlen(str);
     187           0 :     if(len == 0) {
     188           0 :         return(0);
     189             :     }
     190             :     
     191             :     /* The result size could not exceed the input string length
     192             :      * because each char fits inside a byte in all cases :)
     193             :      * In truth, it would be likely less than 1/2 input string length
     194             :      * because each byte is represented by 2 chars. If needed, 
     195             :      * buffer size would be increased by Mul/Add functions.
     196             :      * Finally, we can add one byte for 00 or 10 prefix.
     197             :      */
     198           0 :     ret = xmlSecBufferSetMaxSize(bn, xmlSecBufferGetSize(bn) + len / 2 + 1 + 1);
     199           0 :     if(ret < 0) {
     200           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     201             :                         NULL,
     202             :                         "xmlSecBnRevLookupTable",
     203             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     204           0 :                         "size=%d", len / 2 + 1);
     205           0 :         return (-1);
     206             :     }
     207             : 
     208             :     /* figure out if it is positive or negative number */
     209           0 :     positive = 1;
     210           0 :     i = 0;
     211           0 :     while(i < len) {
     212           0 :         ch = str[i++];
     213             : 
     214             :         /* skip spaces */
     215           0 :         if(isspace(ch)) {
     216           0 :                 continue;
     217             :         } 
     218             :         
     219             :         /* check if it is + or - */
     220           0 :         if(ch == '+') {
     221           0 :             positive = 1;
     222           0 :             break;
     223           0 :         } else if(ch == '-') {
     224           0 :             positive = 0;
     225           0 :             break;
     226             :         }
     227             : 
     228             :         /* otherwise, it must be start of the number */
     229           0 :         nn = xmlSecBnLookupTable[ch];
     230           0 :         if((nn >= 0) && ((xmlSecSize)nn < base)) {
     231           0 :             xmlSecAssert2(i > 0, -1);
     232             : 
     233             :             /* no sign, positive by default */
     234           0 :             positive = 1;
     235           0 :             --i; /* make sure that we will look at this character in next loop */
     236           0 :             break;
     237             :         } else {
     238           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     239             :                         NULL,
     240             :                         NULL,
     241             :                         XMLSEC_ERRORS_R_INVALID_DATA,
     242             :                         "char=%c;base=%d", 
     243             :                         ch, base);
     244           0 :                 return (-1);
     245             :         }
     246             :     }
     247             : 
     248             :     /* now parse the number itself */
     249           0 :     while(i < len) {
     250           0 :         ch = str[i++];
     251           0 :         if(isspace(ch)) {
     252           0 :                 continue;
     253             :         }
     254             : 
     255             :         xmlSecAssert2(ch <= sizeof(xmlSecBnLookupTable), -1);
     256           0 :         nn = xmlSecBnLookupTable[ch];
     257           0 :         if((nn < 0) || ((xmlSecSize)nn > base)) {
     258           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     259             :                         NULL,
     260             :                         NULL,
     261             :                         XMLSEC_ERRORS_R_INVALID_DATA,
     262             :                         "char=%c;base=%d", 
     263             :                         ch, base);
     264           0 :                 return (-1);
     265             :         }
     266             : 
     267           0 :         ret = xmlSecBnMul(bn, base);
     268           0 :         if(ret < 0) {
     269           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     270             :                         NULL,
     271             :                         "xmlSecBnMul",
     272             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     273             :                         "base=%d", base);
     274           0 :                 return (-1);
     275             :         }
     276             : 
     277           0 :         ret = xmlSecBnAdd(bn, nn);
     278           0 :         if(ret < 0) {
     279           0 :                 xmlSecError(XMLSEC_ERRORS_HERE,
     280             :                         NULL,
     281             :                         "xmlSecBnAdd",
     282             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     283             :                         "base=%d", base);
     284           0 :                 return (-1);
     285             : }       
     286             :     }
     287             : 
     288             :     /* check if we need to add 00 prefix, do this for empty bn too */
     289           0 :     data = xmlSecBufferGetData(bn);
     290           0 :     size = xmlSecBufferGetSize(bn);
     291           0 :     if(((size > 0) && (data[0] > 127)) || (size == 0))  {
     292           0 :         ch = 0;
     293           0 :         ret = xmlSecBufferPrepend(bn, &ch, 1);
     294           0 :         if(ret < 0) {
     295           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     296             :                 NULL,
     297             :                 "xmlSecBufferPrepend",
     298             :                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
     299             :                 "base=%d", base);
     300           0 :             return (-1);
     301             :         }
     302             :     }
     303             : 
     304             :     /* do 2's compliment and add 1 to represent negative value */
     305           0 :     if(positive == 0) {
     306           0 :         data = xmlSecBufferGetData(bn);
     307           0 :         size = xmlSecBufferGetSize(bn);
     308           0 :         for(i = 0; i < size; ++i) {
     309           0 :             data[i] ^= 0xFF;
     310             :         }
     311             :         
     312           0 :         ret = xmlSecBnAdd(bn, 1);
     313           0 :         if(ret < 0) {
     314           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     315             :                 NULL,
     316             :                 "xmlSecBnAdd",
     317             :                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
     318             :                 "base=%d", base);
     319           0 :             return (-1);
     320             :         }
     321             :     }
     322             : 
     323           0 :     return(0);
     324             : }
     325             : 
     326             : /**
     327             :  * xmlSecBnToString:
     328             :  * @bn:         the pointer to BN.
     329             :  * @base:       the base for returned string.
     330             :  *
     331             :  * Writes @bn to string with base @base. Caller is responsible for 
     332             :  * freeing returned string with @xmlFree.
     333             :  *
     334             :  * Returns: the string represenataion if BN or a NULL if an error occurs.
     335             :  */
     336             : xmlChar* 
     337           0 : xmlSecBnToString(xmlSecBnPtr bn, xmlSecSize base) {
     338             :     xmlSecBn bn2;
     339           0 :     int positive = 1;
     340             :     xmlChar* res;
     341             :     xmlSecSize i, len, size;
     342             :     xmlSecByte* data;
     343             :     int ret;
     344             :     int nn;
     345             :     xmlChar ch;
     346             : 
     347           0 :     xmlSecAssert2(bn != NULL, NULL);
     348           0 :     xmlSecAssert2(base > 1, NULL);
     349           0 :     xmlSecAssert2(base <= sizeof(xmlSecBnRevLookupTable), NULL);
     350             : 
     351             : 
     352             :     /* copy bn */
     353           0 :     data = xmlSecBufferGetData(bn);
     354           0 :     size = xmlSecBufferGetSize(bn);
     355           0 :     ret = xmlSecBnInitialize(&bn2, size);
     356           0 :     if(ret < 0) {
     357           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     358             :             NULL,
     359             :             "xmlSecBnCreate",
     360             :             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     361             :             "size=%d", size);
     362           0 :         return (NULL);
     363             :     }
     364             :     
     365           0 :     ret = xmlSecBnSetData(&bn2, data, size);
     366           0 :     if(ret < 0) {
     367           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     368             :             NULL,
     369             :             "xmlSecBnSetData",
     370             :             XMLSEC_ERRORS_R_XMLSEC_FAILED,
     371             :             "size=%d", size);
     372           0 :         xmlSecBnFinalize(&bn2);
     373           0 :         return (NULL);
     374             :     }
     375             : 
     376             :     /* check if it is a negative number or not */
     377           0 :     data = xmlSecBufferGetData(&bn2);
     378           0 :     size = xmlSecBufferGetSize(&bn2);
     379           0 :     if((size > 0) && (data[0] > 127)) {
     380             :         /* subtract 1 and do 2's compliment */
     381           0 :         ret = xmlSecBnAdd(&bn2, -1);
     382           0 :         if(ret < 0) {
     383           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     384             :                         NULL,
     385             :                         "xmlSecBnAdd",
     386             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     387             :                         "size=%d", size);
     388           0 :             xmlSecBnFinalize(&bn2);
     389           0 :             return (NULL);
     390             :         }
     391           0 :         for(i = 0; i < size; ++i) {
     392           0 :             data[i] ^= 0xFF;
     393             :         }
     394             : 
     395           0 :         positive = 0;
     396             :     } else {
     397           0 :         positive = 1;
     398             :     }
     399             : 
     400             :     /* Result string len is
     401             :      *      len = log base (256) * <bn size>
     402             :      * Since the smallest base == 2 then we can get away with 
     403             :      *      len = 8 * <bn size>
     404             :      */
     405           0 :     len = 8 * size + 1 + 1;
     406           0 :     res = (xmlChar*)xmlMalloc(len + 1);
     407           0 :     if(res == NULL) {
     408           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
     409             :                             NULL,
     410             :                             NULL,
     411             :                             XMLSEC_ERRORS_R_MALLOC_FAILED,
     412             :                             "len=%d", len);
     413           0 :         xmlSecBnFinalize(&bn2);
     414           0 :         return (NULL);
     415             :     }
     416           0 :     memset(res, 0, len + 1);
     417             : 
     418           0 :     for(i = 0; (xmlSecBufferGetSize(&bn2) > 0) && (i < len); i++) {
     419           0 :         if(xmlSecBnDiv(&bn2, base, &nn) < 0) {
     420           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     421             :                         NULL,
     422             :                         "xmlSecBnDiv",
     423             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     424             :                         "base=%d", base);
     425           0 :             xmlFree(res);
     426           0 :             xmlSecBnFinalize(&bn2);
     427           0 :             return (NULL);
     428             :         }
     429           0 :         xmlSecAssert2((size_t)nn < sizeof(xmlSecBnRevLookupTable), NULL);
     430           0 :         res[i] = xmlSecBnRevLookupTable[nn];
     431             :     }
     432           0 :     xmlSecAssert2(i < len, NULL);
     433             : 
     434             :     /* we might have '0' at the beggining, remove it but keep one zero */
     435           0 :     for(len = i; (len > 1) && (res[len - 1] == '0'); len--);
     436           0 :     res[len] = '\0';
     437             : 
     438             :     /* add "-" for negative numbers */
     439           0 :     if(positive == 0) {
     440           0 :         res[len] = '-';
     441           0 :         res[++len] = '\0';
     442             :     }
     443             : 
     444             :     /* swap the string because we wrote it in reverse order */
     445           0 :     for(i = 0; i < len / 2; i++) {
     446           0 :         ch = res[i];
     447           0 :         res[i] = res[len - i - 1];
     448           0 :         res[len - i - 1] = ch;
     449             :     }
     450             : 
     451           0 :     xmlSecBnFinalize(&bn2);
     452           0 :     return(res);
     453             : }
     454             : 
     455             : /**
     456             :  * xmlSecBnFromHexString:
     457             :  * @bn:         the pointer to BN.
     458             :  * @str:        the string with BN.
     459             :  *
     460             :  * Reads @bn from hex string @str.
     461             :  *
     462             :  * Returns: 0 on success or a negative value if an error occurs.
     463             :  */
     464             : int 
     465           0 : xmlSecBnFromHexString(xmlSecBnPtr bn, const xmlChar* str) {
     466           0 :     return(xmlSecBnFromString(bn, str, 16));
     467             : }
     468             : 
     469             : /**
     470             :  * xmlSecBnToHexString:
     471             :  * @bn:         the pointer to BN.
     472             :  *
     473             :  * Writes @bn to hex string. Caller is responsible for 
     474             :  * freeing returned string with @xmlFree.
     475             :  *
     476             :  * Returns: the string represenataion if BN or a NULL if an error occurs.
     477             :  */
     478             : xmlChar* 
     479           0 : xmlSecBnToHexString(xmlSecBnPtr bn) {
     480           0 :     return(xmlSecBnToString(bn, 16));
     481             : }
     482             : 
     483             : /**
     484             :  * xmlSecBnFromDecString:
     485             :  * @bn:         the pointer to BN.
     486             :  * @str:        the string with BN.
     487             :  *
     488             :  * Reads @bn from decimal string @str.
     489             :  *
     490             :  * Returns: 0 on success or a negative value if an error occurs.
     491             :  */
     492             : int 
     493           0 : xmlSecBnFromDecString(xmlSecBnPtr bn, const xmlChar* str) {
     494           0 :     return(xmlSecBnFromString(bn, str, 10));
     495             : }
     496             : 
     497             : /**
     498             :  * xmlSecBnToDecString:
     499             :  * @bn:         the pointer to BN.
     500             :  *
     501             :  * Writes @bn to decimal string. Caller is responsible for 
     502             :  * freeing returned string with @xmlFree.
     503             :  *
     504             :  * Returns: the string represenataion if BN or a NULL if an error occurs.
     505             :  */
     506             : xmlChar* 
     507           0 : xmlSecBnToDecString(xmlSecBnPtr bn) {
     508           0 :     return(xmlSecBnToString(bn, 10));
     509             : }
     510             : 
     511             : /**
     512             :  * xmlSecBnMul:
     513             :  * @bn:                 the pointer to BN.
     514             :  * @multiplier:         the multiplier.
     515             :  *
     516             :  * Multiplies @bn with @multiplier.
     517             :  *
     518             :  * Returns: 0 on success or a negative value if an error occurs.
     519             :  */
     520             : int 
     521           0 : xmlSecBnMul(xmlSecBnPtr bn, int multiplier) {
     522             :     xmlSecByte* data;
     523             :     int over;
     524             :     xmlSecSize i;
     525             :     xmlSecByte ch;
     526             :     int ret;
     527             : 
     528           0 :     xmlSecAssert2(bn != NULL, -1);
     529           0 :     xmlSecAssert2(multiplier > 0, -1);
     530             : 
     531           0 :     if(multiplier == 1) {
     532           0 :         return(0);
     533             :     }
     534             : 
     535           0 :     data = xmlSecBufferGetData(bn);
     536           0 :     i = xmlSecBufferGetSize(bn);
     537           0 :     over = 0; 
     538           0 :     while(i > 0) {
     539           0 :         xmlSecAssert2(data != NULL, -1);
     540             : 
     541           0 :         over    = over + multiplier * data[--i];
     542           0 :         data[i] = over % 256;
     543           0 :         over    = over / 256;
     544             :     }
     545             :     
     546           0 :     while(over > 0) {
     547           0 :         ch      = over % 256;
     548           0 :         over    = over / 256;
     549             :         
     550           0 :         ret = xmlSecBufferPrepend(bn, &ch, 1);
     551           0 :         if(ret < 0) {
     552           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     553             :                         NULL,
     554             :                         "xmlSecBufferPrepend",
     555             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     556             :                         "size=1");
     557           0 :             return (-1);
     558             :         }
     559             :     }
     560             :     
     561           0 :     return(0);
     562             : }
     563             : 
     564             : /**
     565             :  * xmlSecBnDiv:
     566             :  * @bn:         the pointer to BN.
     567             :  * @divider:    the divider
     568             :  * @mod:        the pointer for modulus result.
     569             :  *
     570             :  * Divides @bn by @divider and places modulus into @mod.
     571             :  *
     572             :  * Returns: 0 on success or a negative value if an error occurs.
     573             :  */
     574             : int 
     575           0 : xmlSecBnDiv(xmlSecBnPtr bn, int divider, int* mod) {
     576             :     int over;
     577             :     xmlSecSize i, size;
     578             :     xmlSecByte* data;
     579             :     int ret;
     580             : 
     581           0 :     xmlSecAssert2(bn != NULL, -1);
     582           0 :     xmlSecAssert2(divider > 0, -1);
     583           0 :     xmlSecAssert2(mod != NULL, -1);
     584             : 
     585           0 :     if(divider == 1) {
     586           0 :         return(0);
     587             :     }
     588             : 
     589           0 :     data = xmlSecBufferGetData(bn);
     590           0 :     size = xmlSecBufferGetSize(bn);
     591           0 :     for(over = 0, i = 0; i < size; i++) {
     592           0 :         xmlSecAssert2(data != NULL, -1);
     593             : 
     594           0 :         over    = over * 256 + data[i];
     595           0 :         data[i] = over / divider;
     596           0 :         over    = over % divider;
     597             :     }
     598           0 :     (*mod) = over;
     599             :     
     600             :     /* remove leading zeros */
     601           0 :     for(i = 0; i < size; i++) {
     602           0 :         xmlSecAssert2(data != NULL, -1);
     603             : 
     604           0 :         if(data[i] != 0) {
     605           0 :             break;
     606             :         }
     607             :     }
     608           0 :     if(i > 0) {
     609           0 :         ret = xmlSecBufferRemoveHead(bn, i);
     610           0 :         if(ret < 0) {
     611           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     612             :                         NULL,
     613             :                         "xmlSecBufferRemoveHead",
     614             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     615             :                         "size=%d", i);
     616           0 :             return (-1);
     617             :         }
     618             :     }
     619           0 :     return(0);
     620             : }
     621             : 
     622             : /**
     623             :  * xmlSecBnAdd:
     624             :  * @bn:         the pointer to BN.
     625             :  * @delta:      the delta.
     626             :  *
     627             :  * Adds @delta to @bn.
     628             :  *
     629             :  * Returns: 0 on success or a negative value if an error occurs.
     630             :  */
     631             : int 
     632           0 : xmlSecBnAdd(xmlSecBnPtr bn, int delta) {
     633             :     int over, tmp;
     634             :     xmlSecByte* data;
     635             :     xmlSecSize i;
     636             :     xmlSecByte ch;
     637             :     int ret;
     638             : 
     639           0 :     xmlSecAssert2(bn != NULL, -1);
     640             : 
     641           0 :     if(delta == 0) {
     642           0 :         return(0);
     643             :     }
     644             : 
     645           0 :     data = xmlSecBufferGetData(bn);
     646           0 :     if(delta > 0) {
     647           0 :         for(over = delta, i = xmlSecBufferGetSize(bn); (i > 0) && (over > 0) ;) {
     648           0 :                 xmlSecAssert2(data != NULL, -1);
     649             :         
     650           0 :             tmp     = data[--i];
     651           0 :                 over   += tmp;
     652           0 :                 data[i] = over % 256;
     653           0 :                 over    = over / 256;
     654             :         }
     655             :     
     656           0 :         while(over > 0) {
     657           0 :                 ch      = over % 256;
     658           0 :                 over    = over / 256;
     659             :         
     660           0 :                 ret = xmlSecBufferPrepend(bn, &ch, 1);
     661           0 :                 if(ret < 0) {
     662           0 :                     xmlSecError(XMLSEC_ERRORS_HERE,
     663             :                                 NULL,
     664             :                                 "xmlSecBufferPrepend",
     665             :                                 XMLSEC_ERRORS_R_XMLSEC_FAILED,
     666             :                                 "size=1");
     667           0 :                     return (-1);
     668             :                 }
     669             :         }
     670             :     } else {
     671           0 :         for(over = -delta, i = xmlSecBufferGetSize(bn); (i > 0) && (over > 0);) {
     672           0 :                 xmlSecAssert2(data != NULL, -1);
     673             :         
     674           0 :             tmp     = data[--i];
     675           0 :             if(tmp < over) {
     676           0 :                 data[i] = 0;
     677           0 :                 over = (over - tmp) / 256;
     678             :             } else {
     679           0 :                 data[i] = tmp - over;
     680           0 :                 over = 0;
     681             :             }
     682             :         }
     683             :     }
     684           0 :     return(0);
     685             : }
     686             : 
     687             : /**
     688             :  * xmlSecBnReverse:
     689             :  * @bn:         the pointer to BN.
     690             :  *
     691             :  * Reverses bytes order in @bn.
     692             :  *
     693             :  * Returns: 0 on success or a negative value if an error occurs.
     694             :  */
     695             : int 
     696           0 : xmlSecBnReverse(xmlSecBnPtr bn) {
     697             :     xmlSecByte* data;
     698             :     xmlSecSize i, j, size;
     699             :     xmlSecByte ch;
     700             : 
     701           0 :     xmlSecAssert2(bn != NULL, -1);
     702             : 
     703           0 :     data = xmlSecBufferGetData(bn);
     704           0 :     size = xmlSecBufferGetSize(bn);
     705           0 :     for(i = 0, j = size - 1; i < size / 2; ++i, --j) {
     706           0 :         xmlSecAssert2(data != NULL, -1);
     707             : 
     708           0 :         ch       = data[i];
     709           0 :         data[i]  = data[j];
     710           0 :         data[j]  = ch;
     711             :     }    
     712             : 
     713           0 :     return(0);
     714             : }
     715             : 
     716             : /**
     717             :  * xmlSecBnCompare:
     718             :  * @bn:         the pointer to BN.
     719             :  * @data:       the data to compare BN to.
     720             :  * @dataSize:   the @data size.
     721             :  *
     722             :  * Compares the @bn with @data.
     723             :  *
     724             :  * Returns: 0 if data is equal, negative value if @bn is less or positive value if @bn
     725             :  * is greater than @data.
     726             :  */
     727             : int 
     728           0 : xmlSecBnCompare(xmlSecBnPtr bn, const xmlSecByte* data, xmlSecSize dataSize) {
     729             :     xmlSecByte* bnData;
     730             :     xmlSecSize bnSize;
     731             : 
     732           0 :     xmlSecAssert2(bn != NULL, -1);
     733             : 
     734           0 :     bnData = xmlSecBnGetData(bn);
     735           0 :     bnSize = xmlSecBnGetSize(bn);
     736             : 
     737             :     /* skip zeros in the beggining */
     738           0 :     while((dataSize > 0) && (data != 0) && (data[0] == 0)) {
     739           0 :         ++data;
     740           0 :         --dataSize;
     741             :     }
     742           0 :     while((bnSize > 0) && (bnData != 0) && (bnData[0] == 0)) {
     743           0 :         ++bnData;
     744           0 :         --bnSize;
     745             :     }
     746             : 
     747           0 :     if(((bnData == NULL) || (bnSize == 0)) && ((data == NULL) || (dataSize == 0))) {
     748           0 :         return(0);
     749           0 :     } else if((bnData == NULL) || (bnSize == 0)) {
     750           0 :         return(-1);
     751           0 :     } else if((data == NULL) || (dataSize == 0)) {
     752           0 :         return(1);
     753           0 :     } else if(bnSize < dataSize) {
     754           0 :         return(-1);
     755           0 :     } else if(bnSize > dataSize) {
     756           0 :         return(-1);
     757             :     } 
     758             : 
     759           0 :     xmlSecAssert2(bnData != NULL, -1);
     760           0 :     xmlSecAssert2(data != NULL, -1);
     761           0 :     xmlSecAssert2(bnSize == dataSize, -1);
     762             : 
     763           0 :     return(memcmp(bnData, data, dataSize));
     764             : }
     765             : 
     766             : /**
     767             :  * xmlSecBnCompareReverse:
     768             :  * @bn:         the pointer to BN.
     769             :  * @data:       the data to compare BN to.
     770             :  * @dataSize:   the @data size.
     771             :  *
     772             :  * Compares the @bn with reverse @data.
     773             :  *
     774             :  * Returns: 0 if data is equal, negative value if @bn is less or positive value if @bn
     775             :  * is greater than @data.
     776             :  */
     777             : int 
     778           0 : xmlSecBnCompareReverse(xmlSecBnPtr bn, const xmlSecByte* data, xmlSecSize dataSize) {
     779             :     xmlSecByte* bnData;
     780             :     xmlSecSize bnSize;
     781             :     xmlSecSize i, j;
     782             : 
     783           0 :     xmlSecAssert2(bn != NULL, -1);
     784             : 
     785           0 :     bnData = xmlSecBnGetData(bn);
     786           0 :     bnSize = xmlSecBnGetSize(bn);
     787             : 
     788             :     /* skip zeros in the beggining */
     789           0 :     while((dataSize > 0) && (data != 0) && (data[dataSize - 1] == 0)) {
     790           0 :         --dataSize;
     791             :     }
     792           0 :     while((bnSize > 0) && (bnData != 0) && (bnData[0] == 0)) {
     793           0 :         ++bnData;
     794           0 :         --bnSize;
     795             :     }
     796             : 
     797           0 :     if(((bnData == NULL) || (bnSize == 0)) && ((data == NULL) || (dataSize == 0))) {
     798           0 :         return(0);
     799           0 :     } else if((bnData == NULL) || (bnSize == 0)) {
     800           0 :         return(-1);
     801           0 :     } else if((data == NULL) || (dataSize == 0)) {
     802           0 :         return(1);
     803           0 :     } else if(bnSize < dataSize) {
     804           0 :         return(-1);
     805           0 :     } else if(bnSize > dataSize) {
     806           0 :         return(-1);
     807             :     } 
     808             : 
     809           0 :     xmlSecAssert2(bnData != NULL, -1);
     810           0 :     xmlSecAssert2(data != NULL, -1);
     811           0 :     xmlSecAssert2(bnSize == dataSize, -1);
     812           0 :     for(i = 0, j = dataSize - 1; i < dataSize; ++i, --j) {
     813           0 :         if(bnData[i] < data[j]) {
     814           0 :             return(-1);
     815           0 :         } else if(data[j] < bnData[i]) {
     816           0 :             return(1);
     817             :         }
     818             :     }
     819             : 
     820           0 :     return(0);
     821             : }
     822             : 
     823             : /**
     824             :  * xmlSecBnGetNodeValue:
     825             :  * @bn:         the pointer to BN.
     826             :  * @cur:        the poitner to an XML node.
     827             :  * @format:     the BN format.
     828             :  * @reverse:    if set then reverse read buffer after reading.
     829             :  *
     830             :  * Converts the node content from @format to @bn.
     831             :  *
     832             :  * Returns: 0 on success and a negative values if an error occurs.
     833             :  */
     834             : int 
     835           0 : xmlSecBnGetNodeValue(xmlSecBnPtr bn, xmlNodePtr cur, xmlSecBnFormat format, int reverse) {
     836             :     xmlChar* content;
     837             :     int ret;
     838             : 
     839           0 :     xmlSecAssert2(bn != NULL, -1);
     840           0 :     xmlSecAssert2(cur != NULL, -1);
     841             : 
     842           0 :     switch(format) {
     843             :     case xmlSecBnBase64:
     844           0 :         ret = xmlSecBufferBase64NodeContentRead(bn, cur);
     845           0 :         if(ret < 0) {
     846           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     847             :                         NULL,
     848             :                         "xmlSecBufferBase64NodeContentRead",
     849             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     850             :                         XMLSEC_ERRORS_NO_MESSAGE);
     851           0 :             return(-1);
     852             :         }
     853           0 :         break;
     854             :     case xmlSecBnHex:
     855           0 :         content = xmlNodeGetContent(cur);
     856           0 :         if(content == NULL) {
     857           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     858             :                         NULL,
     859             :                         "xmlNodeGetContent",
     860             :                         XMLSEC_ERRORS_R_XML_FAILED,
     861             :                         XMLSEC_ERRORS_NO_MESSAGE);
     862           0 :             return(-1);
     863             :         }
     864           0 :         ret = xmlSecBnFromHexString(bn, content);
     865           0 :         if(ret < 0) {
     866           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     867             :                         NULL,
     868             :                         "xmlSecBnFromHexString",
     869             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     870             :                         XMLSEC_ERRORS_NO_MESSAGE);
     871           0 :             xmlFree(content);
     872           0 :             return(-1);
     873             :         }
     874           0 :         xmlFree(content);
     875           0 :         break;
     876             :     case xmlSecBnDec:
     877           0 :         content = xmlNodeGetContent(cur);
     878           0 :         if(content == NULL) {
     879           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     880             :                         NULL,
     881             :                         "xmlNodeGetContent",
     882             :                         XMLSEC_ERRORS_R_XML_FAILED,
     883             :                         XMLSEC_ERRORS_NO_MESSAGE);
     884           0 :             return(-1);
     885             :         }
     886           0 :         ret = xmlSecBnFromDecString(bn, content);
     887           0 :         if(ret < 0) {
     888           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     889             :                         NULL,
     890             :                         "xmlSecBnFromDecString",
     891             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     892             :                         XMLSEC_ERRORS_NO_MESSAGE);
     893           0 :             xmlFree(content);
     894           0 :             return(-1);
     895             :         }
     896           0 :         xmlFree(content);
     897           0 :         break;
     898             :     }
     899             : 
     900           0 :     if(reverse != 0) {
     901           0 :         ret = xmlSecBnReverse(bn);
     902           0 :         if(ret < 0) {
     903           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     904             :                         NULL,
     905             :                         "xmlSecBnReverse",
     906             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     907             :                         XMLSEC_ERRORS_NO_MESSAGE);
     908           0 :             return(-1);
     909             :         }
     910             :     }
     911           0 :     return(0);
     912             : }
     913             : 
     914             : /**
     915             :  * xmlSecBnSetNodeValue:
     916             :  * @bn:                 the pointer to BN.
     917             :  * @cur:                the poitner to an XML node.
     918             :  * @format:             the BN format.
     919             :  * @reverse:            the flag that indicates whether to reverse the buffer before writing.
     920             :  * @addLineBreaks:      the flag; it is equal to 1 then linebreaks will be added before and after new buffer content.
     921             :  *
     922             :  * Converts the @bn and sets it to node content.
     923             :  *
     924             :  * Returns: 0 on success and a negative values if an error occurs.
     925             :  */
     926             : int  
     927           0 : xmlSecBnSetNodeValue(xmlSecBnPtr bn, xmlNodePtr cur, xmlSecBnFormat format, int reverse, int addLineBreaks) {
     928             :     xmlChar* content;
     929             :     int ret;
     930             : 
     931           0 :     xmlSecAssert2(bn != NULL, -1);
     932           0 :     xmlSecAssert2(cur != NULL, -1);
     933             : 
     934           0 :     if(reverse != 0) {
     935           0 :         ret = xmlSecBnReverse(bn);
     936           0 :         if(ret < 0) {
     937           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     938             :                         NULL,
     939             :                         "xmlSecBnReverse",
     940             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     941             :                         XMLSEC_ERRORS_NO_MESSAGE);
     942           0 :             return(-1);
     943             :         }
     944             :     }
     945             : 
     946           0 :     if(addLineBreaks) {
     947           0 :         xmlNodeAddContent(cur, xmlSecStringCR);
     948             :     }
     949             : 
     950           0 :     switch(format) {
     951             :     case xmlSecBnBase64:
     952           0 :         ret = xmlSecBufferBase64NodeContentWrite(bn, cur, xmlSecBase64GetDefaultLineSize());
     953           0 :         if(ret < 0) {
     954           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     955             :                         NULL,
     956             :                         "xmlSecBufferBase64NodeContentWrite",
     957             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     958             :                         XMLSEC_ERRORS_NO_MESSAGE);
     959           0 :             return(-1);
     960             :         }
     961           0 :         break;
     962             :     case xmlSecBnHex:
     963           0 :         content = xmlSecBnToHexString(bn);
     964           0 :         if(content == NULL) {
     965           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     966             :                         NULL,
     967             :                         "xmlSecBnToHexString",
     968             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     969             :                         XMLSEC_ERRORS_NO_MESSAGE);
     970           0 :             xmlFree(content);
     971           0 :             return(-1);
     972             :         }
     973           0 :         xmlNodeSetContent(cur, content);
     974           0 :         xmlFree(content);
     975           0 :         break;
     976             :     case xmlSecBnDec:
     977           0 :         content = xmlSecBnToDecString(bn);
     978           0 :         if(content == NULL) {
     979           0 :             xmlSecError(XMLSEC_ERRORS_HERE,
     980             :                         NULL,
     981             :                         "xmlSecBnToDecString",
     982             :                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
     983             :                         XMLSEC_ERRORS_NO_MESSAGE);
     984           0 :             xmlFree(content);
     985           0 :             return(-1);
     986             :         }
     987           0 :         xmlNodeSetContent(cur, content);
     988           0 :         xmlFree(content);
     989           0 :         break;
     990             :     }
     991             : 
     992           0 :     if(addLineBreaks) {
     993           0 :         xmlNodeAddContent(cur, xmlSecStringCR);
     994             :     }
     995             : 
     996           0 :     return(0);
     997             : }
     998             : 
     999             : /**
    1000             :  * xmlSecBnBlobSetNodeValue:
    1001             :  * @data:       the pointer to BN blob.
    1002             :  * @dataSize:   the size of BN blob.
    1003             :  * @cur:        the poitner to an XML node.
    1004             :  * @format:     the BN format.
    1005             :  * @reverse:    the flag that indicates whether to reverse the buffer before writing.
    1006             :  * @addLineBreaks:  if the flag is equal to 1 then 
    1007             :  *              linebreaks will be added before and after
    1008             :  *              new buffer content.
    1009             :  *
    1010             :  * Converts the @blob and sets it to node content.
    1011             :  *
    1012             :  * Returns: 0 on success and a negative values if an error occurs.
    1013             :  */
    1014             : int  
    1015           0 : xmlSecBnBlobSetNodeValue(const xmlSecByte* data, xmlSecSize dataSize, 
    1016             :                          xmlNodePtr cur, xmlSecBnFormat format, int reverse,
    1017             :                          int addLineBreaks) {
    1018             :     xmlSecBn bn;
    1019             :     int ret;
    1020             : 
    1021           0 :     xmlSecAssert2(data != NULL, -1);
    1022           0 :     xmlSecAssert2(cur != NULL, -1);
    1023             : 
    1024           0 :     ret = xmlSecBnInitialize(&bn, dataSize);
    1025           0 :     if(ret < 0) {
    1026           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1027             :                     NULL,
    1028             :                     "xmlSecBnInitialize",
    1029             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1030             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1031           0 :         return(-1);
    1032             :     }
    1033             : 
    1034           0 :     ret = xmlSecBnSetData(&bn, data, dataSize);
    1035           0 :     if(ret < 0) {
    1036           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1037             :                     NULL,
    1038             :                     "xmlSecBnSetData",
    1039             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1040             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1041           0 :         xmlSecBnFinalize(&bn);
    1042           0 :         return(-1);
    1043             :     }
    1044             : 
    1045           0 :     ret = xmlSecBnSetNodeValue(&bn, cur, format, reverse, addLineBreaks);
    1046           0 :     if(ret < 0) {
    1047           0 :         xmlSecError(XMLSEC_ERRORS_HERE,
    1048             :                     NULL,
    1049             :                     "xmlSecBnSetNodeValue",
    1050             :                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
    1051             :                     XMLSEC_ERRORS_NO_MESSAGE);
    1052           0 :         xmlSecBnFinalize(&bn);
    1053           0 :         return(-1);
    1054             :     }
    1055             : 
    1056           0 :     xmlSecBnFinalize(&bn);
    1057           0 :     return(0);
    1058             : }
    1059             : 
    1060             : 

Generated by: LCOV version 1.10