• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

qca

qca_tools.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
00003  * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018  * 02110-1301  USA
00019  *
00020  */
00021 
00022 #include "qca_tools.h"
00023 
00024 #include "qdebug.h"
00025 
00026 #ifdef Q_OS_UNIX
00027 # include <stdlib.h>
00028 # include <sys/mman.h>
00029 #endif
00030 #include "botantools/botantools.h"
00031 
00032 namespace QCA {
00033 
00034 static bool can_lock()
00035 {
00036 #ifdef Q_OS_UNIX
00037     bool ok = false;
00038 #ifdef MLOCK_NOT_VOID_PTR
00039 # define MLOCK_TYPE char *
00040 # define MLOCK_TYPE_CAST (MLOCK_TYPE)
00041 #else
00042 # define MLOCK_TYPE void *
00043 # define MLOCK_TYPE_CAST
00044 #endif
00045 
00046     MLOCK_TYPE d = MLOCK_TYPE_CAST malloc(256);
00047     if(mlock(d, 256) == 0)
00048     {
00049         munlock(d, 256);
00050         ok = true;
00051     }
00052     free(d);
00053     return ok;
00054 #else
00055     return true;
00056 #endif
00057 }
00058 
00059 // Botan shouldn't throw any exceptions in our init/deinit.
00060 
00061 static Botan::Allocator *alloc = 0;
00062 
00063 void botan_throw_abort()
00064 {
00065     fprintf(stderr, "QCA: Exception from internal Botan\n");
00066     abort();
00067 }
00068 
00069 bool botan_init(int prealloc, bool mmap)
00070 {
00071     // 64k minimum
00072     if(prealloc < 64)
00073         prealloc = 64;
00074 
00075     bool secmem = false;
00076 
00077     try
00078     {
00079         Botan::Builtin_Modules modules;
00080         Botan::Library_State *libstate = new Botan::Library_State(modules.mutex_factory());
00081         libstate->prealloc_size = prealloc * 1024;
00082         Botan::set_global_state(libstate);
00083         Botan::global_state().load(modules);
00084 
00085         if(can_lock())
00086         {
00087             Botan::global_state().set_default_allocator("locking");
00088             secmem = true;
00089         }
00090         else if(mmap)
00091         {
00092             Botan::global_state().set_default_allocator("mmap");
00093             secmem = true;
00094         }
00095         alloc = Botan::Allocator::get(true);
00096     }
00097     catch(std::exception &)
00098     {
00099         fprintf(stderr, "QCA: Error initializing internal Botan\n");
00100         abort();
00101     }
00102 
00103     return secmem;
00104 }
00105 
00106 void botan_deinit()
00107 {
00108     try
00109     {
00110         alloc = 0;
00111         Botan::set_global_state(0);
00112     }
00113     catch(std::exception &)
00114     {
00115         botan_throw_abort();
00116     }
00117 }
00118 
00119 void *botan_secure_alloc(int bytes)
00120 {
00121     try
00122     {
00123         return alloc->allocate((Botan::u32bit)bytes);
00124     }
00125     catch(std::exception &)
00126     {
00127         botan_throw_abort();
00128     }
00129     return 0; // never get here
00130 }
00131 
00132 void botan_secure_free(void *p, int bytes)
00133 {
00134     try
00135     {
00136         alloc->deallocate(p, (Botan::u32bit)bytes);
00137     }
00138     catch(std::exception &)
00139     {
00140         botan_throw_abort();
00141     }
00142 }
00143 
00144 } // end namespace QCA
00145 
00146 void *qca_secure_alloc(int bytes)
00147 {
00148     // allocate enough room to store a size value in front, return a pointer after it
00149     char *c = (char *)QCA::botan_secure_alloc(bytes + sizeof(int));
00150     ((int *)c)[0] = bytes + sizeof(int);
00151     return c + sizeof(int);
00152 }
00153 
00154 void qca_secure_free(void *p)
00155 {
00156     // backtrack to read the size value
00157     char *c = (char *)p;
00158     c -= sizeof(int);
00159     int bytes = ((int *)c)[0];
00160     QCA::botan_secure_free(c, bytes);
00161 }
00162 
00163 void *qca_secure_realloc(void *p, int bytes)
00164 {
00165     // if null, do a plain alloc (just like how realloc() works)
00166     if(!p)
00167         return qca_secure_alloc(bytes);
00168 
00169     // backtrack to read the size value
00170     char *c = (char *)p;
00171     c -= sizeof(int);
00172     int oldsize = ((int *)c)[0] - sizeof(int);
00173 
00174     // alloc the new chunk
00175     char *new_p = (char *)qca_secure_alloc(bytes);
00176     if(!new_p)
00177         return 0;
00178 
00179     // move over the memory from the original block
00180     memmove(new_p, p, qMin(oldsize, bytes));
00181 
00182     // free the original
00183     qca_secure_free(p);
00184 
00185     // done
00186     return new_p;
00187 }
00188 
00189 namespace QCA {
00190 
00191 // secure or non-secure buffer, with trailing 0-byte.
00192 // buffer size of 0 is okay (sbuf/qbuf will be 0).
00193 struct alloc_info
00194 {
00195     bool sec;
00196     char *data;
00197     int size;
00198 
00199     // internal
00200     Botan::SecureVector<Botan::byte> *sbuf;
00201     QByteArray *qbuf;
00202 };
00203 
00204 // note: these functions don't return error if memory allocation/resizing
00205 //   fails..  maybe fix this someday?
00206 
00207 // ai: uninitialized
00208 // size: >= 0
00209 // note: memory will be initially zero'd out
00210 static bool ai_new(alloc_info *ai, int size, bool sec);
00211 
00212 // ai: uninitialized
00213 // from: initialized
00214 static bool ai_copy(alloc_info *ai, const alloc_info *from);
00215 
00216 // ai: initialized
00217 // new_size: >= 0
00218 static bool ai_resize(alloc_info *ai, int new_size);
00219 
00220 // ai: initialized
00221 static void ai_delete(alloc_info *ai);
00222 
00223 bool ai_new(alloc_info *ai, int size, bool sec)
00224 {
00225     if(size < 0)
00226         return false;
00227 
00228     ai->size = size;
00229     ai->sec = sec;
00230 
00231     if(size == 0)
00232     {
00233         ai->sbuf = 0;
00234         ai->qbuf = 0;
00235         ai->data = 0;
00236         return true;
00237     }
00238 
00239     if(sec)
00240     {
00241         try
00242         {
00243             ai->sbuf = new Botan::SecureVector<Botan::byte>((Botan::u32bit)size + 1);
00244         }
00245         catch(std::exception &)
00246         {
00247             botan_throw_abort();
00248             return false; // never get here
00249         }
00250 
00251         (*(ai->sbuf))[size] = 0;
00252         ai->qbuf = 0;
00253         Botan::byte *bp = (Botan::byte *)(*(ai->sbuf));
00254         ai->data = (char *)bp;
00255     }
00256     else
00257     {
00258         ai->sbuf = 0;
00259         ai->qbuf = new QByteArray(size, 0);
00260         ai->data = ai->qbuf->data();
00261     }
00262 
00263     return true;
00264 }
00265 
00266 bool ai_copy(alloc_info *ai, const alloc_info *from)
00267 {
00268     ai->size = from->size;
00269     ai->sec = from->sec;
00270 
00271     if(ai->size == 0)
00272     {
00273         ai->sbuf = 0;
00274         ai->qbuf = 0;
00275         ai->data = 0;
00276         return true;
00277     }
00278 
00279     if(ai->sec)
00280     {
00281         try
00282         {
00283             ai->sbuf = new Botan::SecureVector<Botan::byte>(*(from->sbuf));
00284         }
00285         catch(std::exception &)
00286         {
00287             botan_throw_abort();
00288             return false; // never get here
00289         }
00290 
00291         ai->qbuf = 0;
00292         Botan::byte *bp = (Botan::byte *)(*(ai->sbuf));
00293         ai->data = (char *)bp;
00294     }
00295     else
00296     {
00297         ai->sbuf = 0;
00298         ai->qbuf = new QByteArray(*(from->qbuf));
00299         ai->data = ai->qbuf->data();
00300     }
00301 
00302     return true;
00303 }
00304 
00305 bool ai_resize(alloc_info *ai, int new_size)
00306 {
00307     if(new_size < 0)
00308         return false;
00309 
00310     // new size is empty
00311     if(new_size == 0)
00312     {
00313         // we currently aren't empty
00314         if(ai->size > 0)
00315         {
00316             if(ai->sec)
00317             {
00318                 delete ai->sbuf;
00319                 ai->sbuf = 0;
00320             }
00321             else
00322             {
00323                 delete ai->qbuf;
00324                 ai->qbuf = 0;
00325             }
00326 
00327             ai->size = 0;
00328             ai->data = 0;
00329         }
00330 
00331         return true;
00332     }
00333 
00334     if(ai->sec)
00335     {
00336         Botan::SecureVector<Botan::byte> *new_buf;
00337         try
00338         {
00339             new_buf = new Botan::SecureVector<Botan::byte>((Botan::u32bit)new_size + 1);
00340         }
00341         catch(std::exception &)
00342         {
00343             botan_throw_abort();
00344             return false; // never get here
00345         }
00346 
00347         Botan::byte *new_p = (Botan::byte *)(*new_buf);
00348         if(ai->size > 0)
00349         {
00350             const Botan::byte *old_p = (const Botan::byte *)(*(ai->sbuf));
00351             memcpy(new_p, old_p, qMin(new_size, ai->size));
00352             delete ai->sbuf;
00353         }
00354         ai->sbuf = new_buf;
00355         ai->size = new_size;
00356         (*(ai->sbuf))[new_size] = 0;
00357         ai->data = (char *)new_p;
00358     }
00359     else
00360     {
00361         if(ai->size > 0)
00362             ai->qbuf->resize(new_size);
00363         else
00364             ai->qbuf = new QByteArray(new_size, 0);
00365 
00366         ai->size = new_size;
00367         ai->data = ai->qbuf->data();
00368     }
00369 
00370     return true;
00371 }
00372 
00373 void ai_delete(alloc_info *ai)
00374 {
00375     if(ai->size > 0)
00376     {
00377         if(ai->sec)
00378             delete ai->sbuf;
00379         else
00380             delete ai->qbuf;
00381     }
00382 }
00383 
00384 //----------------------------------------------------------------------------
00385 // MemoryRegion
00386 //----------------------------------------------------------------------------
00387 static char blank[] = "";
00388 
00389 class MemoryRegion::Private : public QSharedData
00390 {
00391 public:
00392     alloc_info ai;
00393 
00394     Private(int size, bool sec)
00395     {
00396         ai_new(&ai, size, sec);
00397     }
00398 
00399     Private(const QByteArray &from, bool sec)
00400     {
00401         ai_new(&ai, from.size(), sec);
00402         memcpy(ai.data, from.data(), ai.size);
00403     }
00404 
00405     Private(const Private &from) : QSharedData(from)
00406     {
00407         ai_copy(&ai, &from.ai);
00408     }
00409 
00410     ~Private()
00411     {
00412         ai_delete(&ai);
00413     }
00414 
00415     bool resize(int new_size)
00416     {
00417         return ai_resize(&ai, new_size);
00418     }
00419 
00420     void setSecure(bool sec)
00421     {
00422         // if same mode, do nothing
00423         if(ai.sec == sec)
00424             return;
00425 
00426         alloc_info other;
00427         ai_new(&other, ai.size, sec);
00428         memcpy(other.data, ai.data, ai.size);
00429         ai_delete(&ai);
00430         ai = other;
00431     }
00432 };
00433 
00434 MemoryRegion::MemoryRegion()
00435 :_secure(false), d(0)
00436 {
00437 }
00438 
00439 MemoryRegion::MemoryRegion(const char *str)
00440 :_secure(false), d(new Private(QByteArray::fromRawData(str, strlen(str)), false))
00441 {
00442 }
00443 
00444 MemoryRegion::MemoryRegion(const QByteArray &from)
00445 :_secure(false), d(new Private(from, false))
00446 {
00447 }
00448 
00449 MemoryRegion::MemoryRegion(const MemoryRegion &from)
00450 :_secure(from._secure), d(from.d)
00451 {
00452 }
00453 
00454 MemoryRegion::~MemoryRegion()
00455 {
00456 }
00457 
00458 MemoryRegion & MemoryRegion::operator=(const MemoryRegion &from)
00459 {
00460     _secure = from._secure;
00461     d = from.d;
00462     return *this;
00463 }
00464 
00465 MemoryRegion & MemoryRegion::operator=(const QByteArray &from)
00466 {
00467     set(from, false);
00468     return *this;
00469 }
00470 
00471 bool MemoryRegion::isNull() const
00472 {
00473     return (d ? false : true);
00474 }
00475 
00476 bool MemoryRegion::isSecure() const
00477 {
00478     return _secure;
00479 }
00480 
00481 QByteArray MemoryRegion::toByteArray() const
00482 {
00483     if(!d)
00484         return QByteArray();
00485 
00486     if(d->ai.sec)
00487     {
00488         QByteArray buf(d->ai.size, 0);
00489         memcpy(buf.data(), d->ai.data, d->ai.size);
00490         return buf;
00491     }
00492     else
00493     {
00494         if(d->ai.size > 0)
00495             return *(d->ai.qbuf);
00496         else
00497             return QByteArray((int)0, (char)0);
00498     }
00499 }
00500 
00501 MemoryRegion::MemoryRegion(bool secure)
00502 :_secure(secure), d(0)
00503 {
00504 }
00505 
00506 MemoryRegion::MemoryRegion(int size, bool secure)
00507 :_secure(secure), d(new Private(size, secure))
00508 {
00509 }
00510 
00511 MemoryRegion::MemoryRegion(const QByteArray &from, bool secure)
00512 :_secure(secure), d(new Private(from, secure))
00513 {
00514 }
00515 
00516 char *MemoryRegion::data()
00517 {
00518     if(!d)
00519         return blank;
00520     return d->ai.data;
00521 }
00522 
00523 const char *MemoryRegion::data() const
00524 {
00525     if(!d)
00526         return blank;
00527     return d->ai.data;
00528 }
00529 
00530 const char *MemoryRegion::constData() const
00531 {
00532     if(!d)
00533         return blank;
00534     return d->ai.data;
00535 }
00536 
00537 char & MemoryRegion::at(int index)
00538 {
00539     return *(d->ai.data + index);
00540 }
00541 
00542 const char & MemoryRegion::at(int index) const
00543 {
00544     return *(d->ai.data + index);
00545 }
00546 
00547 int MemoryRegion::size() const
00548 {
00549     if(!d)
00550         return 0;
00551     return d->ai.size;
00552 }
00553 
00554 bool MemoryRegion::isEmpty() const
00555 {
00556     if(!d)
00557         return true;
00558     return (d->ai.size > 0 ? false : true);
00559 }
00560 
00561 bool MemoryRegion::resize(int size)
00562 {
00563     if(!d)
00564     {
00565         d = new Private(size, _secure);
00566         return true;
00567     }
00568 
00569     if(d->ai.size == size)
00570         return true;
00571 
00572     return d->resize(size);
00573 }
00574 
00575 void MemoryRegion::set(const QByteArray &from, bool secure)
00576 {
00577     _secure = secure;
00578 
00579     if(!from.isEmpty())
00580         d = new Private(from, secure);
00581     else
00582         d = new Private(0, secure);
00583 }
00584 
00585 void MemoryRegion::setSecure(bool secure)
00586 {
00587     _secure = secure;
00588 
00589     if(!d)
00590     {
00591         d = new Private(0, secure);
00592         return;
00593     }
00594 
00595     d->setSecure(secure);
00596 }
00597 
00598 //----------------------------------------------------------------------------
00599 // SecureArray
00600 //----------------------------------------------------------------------------
00601 SecureArray::SecureArray()
00602 :MemoryRegion(true)
00603 {
00604 }
00605 
00606 SecureArray::SecureArray(int size, char ch)
00607 :MemoryRegion(size, true)
00608 {
00609     // ai_new fills with zeros for us
00610     if(ch != 0)
00611         fill(ch, size);
00612 }
00613 
00614 SecureArray::SecureArray(const char *str)
00615 :MemoryRegion(QByteArray::fromRawData(str, strlen(str)), true)
00616 {
00617 }
00618 
00619 SecureArray::SecureArray(const QByteArray &a)
00620 :MemoryRegion(a, true)
00621 {
00622 }
00623 
00624 SecureArray::SecureArray(const MemoryRegion &a)
00625 :MemoryRegion(a)
00626 {
00627     setSecure(true);
00628 }
00629 
00630 SecureArray::SecureArray(const SecureArray &from)
00631 :MemoryRegion(from)
00632 {
00633 }
00634 
00635 SecureArray::~SecureArray()
00636 {
00637 }
00638 
00639 SecureArray & SecureArray::operator=(const SecureArray &from)
00640 {
00641     MemoryRegion::operator=(from);
00642     return *this;
00643 }
00644 
00645 SecureArray & SecureArray::operator=(const QByteArray &from)
00646 {
00647     MemoryRegion::set(from, true);
00648     return *this;
00649 }
00650 
00651 void SecureArray::clear()
00652 {
00653     MemoryRegion::resize(0);
00654 }
00655 
00656 bool SecureArray::resize(int size)
00657 {
00658     return MemoryRegion::resize(size);
00659 }
00660 
00661 char & SecureArray::operator[](int index)
00662 {
00663     return at(index);
00664 }
00665 
00666 const char & SecureArray::operator[](int index) const
00667 {
00668     return at(index);
00669 }
00670 
00671 char & SecureArray::at(int index)
00672 {
00673     return MemoryRegion::at(index);
00674 }
00675 
00676 const char & SecureArray::at(int index) const
00677 {
00678     return MemoryRegion::at(index);
00679 }
00680 
00681 char *SecureArray::data()
00682 {
00683     return MemoryRegion::data();
00684 }
00685 
00686 const char *SecureArray::data() const
00687 {
00688     return MemoryRegion::data();
00689 }
00690 
00691 const char *SecureArray::constData() const
00692 {
00693     return MemoryRegion::constData();
00694 }
00695 
00696 int SecureArray::size() const
00697 {
00698     return MemoryRegion::size();
00699 }
00700 
00701 bool SecureArray::isEmpty() const
00702 {
00703     return MemoryRegion::isEmpty();
00704 }
00705 
00706 QByteArray SecureArray::toByteArray() const
00707 {
00708     return MemoryRegion::toByteArray();
00709 }
00710 
00711 SecureArray & SecureArray::append(const SecureArray &a)
00712 {
00713     int oldsize = size();
00714     resize(oldsize + a.size());
00715     memcpy(data() + oldsize, a.data(), a.size());
00716     return *this;
00717 }
00718 
00719 bool SecureArray::operator==(const MemoryRegion &other) const
00720 {
00721     if(this == &other)
00722         return true;
00723     if(size() == other.size() && memcmp(data(), other.data(), size()) == 0)
00724         return true;
00725     return false;
00726 }
00727 
00728 SecureArray & SecureArray::operator+=(const SecureArray &a)
00729 {
00730     return append(a);
00731 }
00732 
00733 void SecureArray::fill(char fillChar, int fillToPosition)
00734 {
00735     int len = (fillToPosition == -1) ? size() : qMin(fillToPosition, size());
00736     if(len > 0)
00737         memset(data(), (int)fillChar, len);
00738 }
00739 
00740 void SecureArray::set(const SecureArray &from)
00741 {
00742     *this = from;
00743 }
00744 
00745 void SecureArray::set(const QByteArray &from)
00746 {
00747     *this = from;
00748 }
00749 
00750 const SecureArray operator+(const SecureArray &a, const SecureArray &b)
00751 {
00752     SecureArray c = a;
00753     return c.append(b);
00754 }
00755 
00756 //----------------------------------------------------------------------------
00757 // BigInteger
00758 //----------------------------------------------------------------------------
00759 static void negate_binary(char *a, int size)
00760 {
00761     // negate = two's compliment + 1
00762     bool done = false;
00763     for(int n = size - 1; n >= 0; --n)
00764     {
00765         a[n] = ~a[n];
00766         if(!done)
00767         {
00768             if((unsigned char)a[n] < 0xff)
00769             {
00770                 ++a[n];
00771                 done = true;
00772             }
00773             else
00774                 a[n] = 0;
00775         }
00776     }
00777 }
00778 
00779 class BigInteger::Private : public QSharedData
00780 {
00781 public:
00782     Botan::BigInt n;
00783 };
00784 
00785 BigInteger::BigInteger()
00786 {
00787     d = new Private;
00788 }
00789 
00790 BigInteger::BigInteger(int i)
00791 {
00792     d = new Private;
00793     if(i < 0)
00794     {
00795         d->n = Botan::BigInt(i * (-1));
00796         d->n.set_sign(Botan::BigInt::Negative);
00797     }
00798     else
00799     {
00800         d->n = Botan::BigInt(i);
00801         d->n.set_sign(Botan::BigInt::Positive);
00802     }
00803 }
00804 
00805 BigInteger::BigInteger(const char *c)
00806 {
00807     d = new Private;
00808     fromString(QString(c));
00809 }
00810 
00811 BigInteger::BigInteger(const QString &s)
00812 {
00813     d = new Private;
00814     fromString(s);
00815 }
00816 
00817 BigInteger::BigInteger(const SecureArray &a)
00818 {
00819     d = new Private;
00820     fromArray(a);
00821 }
00822 
00823 BigInteger::BigInteger(const BigInteger &from)
00824 {
00825     *this = from;
00826 }
00827 
00828 BigInteger::~BigInteger()
00829 {
00830 }
00831 
00832 BigInteger & BigInteger::operator=(const BigInteger &from)
00833 {
00834     d = from.d;
00835     return *this;
00836 }
00837 
00838 BigInteger & BigInteger::operator+=(const BigInteger &i)
00839 {
00840     d->n += i.d->n;
00841     return *this;
00842 }
00843 
00844 BigInteger & BigInteger::operator-=(const BigInteger &i)
00845 {
00846     d->n -= i.d->n;
00847     return *this;
00848 }
00849 
00850 BigInteger & BigInteger::operator*=(const BigInteger &i)
00851 {
00852     d->n *= i.d->n;
00853     return *this;
00854 }
00855 
00856 BigInteger & BigInteger::operator/=(const BigInteger &i)
00857 {
00858     try
00859     {
00860         d->n /= i.d->n;
00861     }
00862     catch(std::exception &)
00863     {
00864         fprintf(stderr, "QCA: Botan integer division error\n");
00865         abort();
00866     }
00867     return *this;
00868 }
00869 
00870 BigInteger & BigInteger::operator%=(const BigInteger &i)
00871 {
00872     try
00873     {
00874         d->n %= i.d->n;
00875     }
00876     catch(std::exception &)
00877     {
00878         fprintf(stderr, "QCA: Botan integer division error\n");
00879         abort();
00880     }
00881     return *this;
00882 }
00883 
00884 BigInteger & BigInteger::operator=(const QString &s)
00885 {
00886     fromString(s);
00887     return *this;
00888 }
00889 
00890 int BigInteger::compare(const BigInteger &n) const
00891 {
00892     return ( (d->n).cmp( n.d->n, true) );
00893 }
00894 
00895 QTextStream &operator<<(QTextStream &stream, const BigInteger& b)
00896 {
00897     stream << b.toString();
00898     return stream;
00899 }
00900 
00901 SecureArray BigInteger::toArray() const
00902 {
00903     int size = d->n.encoded_size(Botan::BigInt::Binary);
00904 
00905     // return at least 8 bits
00906     if(size == 0)
00907     {
00908         SecureArray a(1);
00909         a[0] = 0;
00910         return a;
00911     }
00912 
00913     int offset = 0;
00914     SecureArray a;
00915 
00916     // make room for a sign bit if needed
00917     if(d->n.get_bit((size * 8) - 1))
00918     {
00919         ++size;
00920         a.resize(size);
00921         a[0] = 0;
00922         ++offset;
00923     }
00924     else
00925         a.resize(size);
00926 
00927     Botan::BigInt::encode((Botan::byte *)a.data() + offset, d->n, Botan::BigInt::Binary);
00928 
00929     if(d->n.is_negative())
00930         negate_binary(a.data(), a.size());
00931 
00932     return a;
00933 }
00934 
00935 void BigInteger::fromArray(const SecureArray &_a)
00936 {
00937     if(_a.isEmpty())
00938     {
00939         d->n = Botan::BigInt(0);
00940         return;
00941     }
00942     SecureArray a = _a;
00943 
00944     Botan::BigInt::Sign sign = Botan::BigInt::Positive;
00945     if(a[0] & 0x80)
00946         sign = Botan::BigInt::Negative;
00947 
00948     if(sign == Botan::BigInt::Negative)
00949         negate_binary(a.data(), a.size());
00950 
00951     d->n = Botan::BigInt::decode((const Botan::byte *)a.data(), a.size(), Botan::BigInt::Binary);
00952     d->n.set_sign(sign);
00953 }
00954 
00955 QString BigInteger::toString() const
00956 {
00957     QByteArray cs;
00958     try
00959     {
00960         cs.resize(d->n.encoded_size(Botan::BigInt::Decimal));
00961         Botan::BigInt::encode((Botan::byte *)cs.data(), d->n, Botan::BigInt::Decimal);
00962     }
00963     catch(std::exception &)
00964     {
00965         return QString();
00966     }
00967 
00968     QString str;
00969     if(d->n.is_negative())
00970         str += '-';
00971     str += QString::fromLatin1(cs);
00972     return str;
00973 }
00974 
00975 bool BigInteger::fromString(const QString &s)
00976 {
00977     if(s.isEmpty())
00978         return false;
00979     QByteArray cs = s.toLatin1();
00980 
00981     bool neg = false;
00982     if(s[0] == '-')
00983         neg = true;
00984 
00985     try
00986     {
00987         d->n = Botan::BigInt::decode((const Botan::byte *)cs.data() + (neg ? 1 : 0), cs.length() - (neg ? 1 : 0), Botan::BigInt::Decimal);
00988     }
00989     catch(std::exception &)
00990     {
00991         return false;
00992     }
00993 
00994     if(neg)
00995         d->n.set_sign(Botan::BigInt::Negative);
00996     else
00997         d->n.set_sign(Botan::BigInt::Positive);
00998     return true;
00999 }
01000 
01001 }

qca

Skip menu "qca"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal