diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/asn1/asn1_print.cpp | 14 | ||||
-rw-r--r-- | src/lib/asn1/asn1_print.h | 10 | ||||
-rw-r--r-- | src/lib/math/bigint/big_code.cpp | 22 | ||||
-rw-r--r-- | src/lib/math/bigint/big_io.cpp | 17 |
4 files changed, 42 insertions, 21 deletions
diff --git a/src/lib/asn1/asn1_print.cpp b/src/lib/asn1/asn1_print.cpp index 34c671483..1a1654fef 100644 --- a/src/lib/asn1/asn1_print.cpp +++ b/src/lib/asn1/asn1_print.cpp @@ -172,11 +172,7 @@ void ASN1_Formatter::decode(std::ostream& output, data.decode(number, ASN1_Type::Enumerated, class_tag); } - std::vector<uint8_t> rep = BigInt::encode(number); - if(rep.empty()) // if zero - rep.resize(1); - - output << format(type_tag, class_tag, level, length, hex_encode(rep)); + output << format(type_tag, class_tag, level, length, format_bn(number)); } else if(type_tag == ASN1_Type::Boolean) { @@ -324,4 +320,12 @@ std::string ASN1_Pretty_Printer::format_bin(ASN1_Type /*type_tag*/, return hex_encode(vec); } +std::string ASN1_Pretty_Printer::format_bn(const BigInt& bn) const + { + if(bn.bits() < 16) + return bn.to_dec_string(); + else + return bn.to_hex_string(); + } + } diff --git a/src/lib/asn1/asn1_print.h b/src/lib/asn1/asn1_print.h index 53ed42de6..94dc48d6a 100644 --- a/src/lib/asn1/asn1_print.h +++ b/src/lib/asn1/asn1_print.h @@ -14,6 +14,7 @@ namespace Botan { +class BigInt; class BER_Decoder; /** @@ -58,13 +59,18 @@ class BOTAN_PUBLIC_API(2,4) ASN1_Formatter /** * This is called to format binary elements that we don't know how to - * convert to a string The result will be passed as value to format; the + * convert to a string. The result will be passed as value to format; the * tags are included as a hint to aid decoding. */ virtual std::string format_bin(ASN1_Type type_tag, ASN1_Class class_tag, const std::vector<uint8_t>& vec) const = 0; + /** + * This is called to format integers + */ + virtual std::string format_bn(const BigInt& bn) const = 0; + private: void decode(std::ostream& output, BER_Decoder& decoder, @@ -114,6 +120,8 @@ class BOTAN_PUBLIC_API(2,4) ASN1_Pretty_Printer final : public ASN1_Formatter ASN1_Class class_tag, const std::vector<uint8_t>& vec) const override; + std::string format_bn(const BigInt& bn) const override; + const size_t m_print_limit; const size_t m_print_binary_limit; const size_t m_initial_level; diff --git a/src/lib/math/bigint/big_code.cpp b/src/lib/math/bigint/big_code.cpp index 3ff31b639..c31221333 100644 --- a/src/lib/math/bigint/big_code.cpp +++ b/src/lib/math/bigint/big_code.cpp @@ -17,7 +17,10 @@ std::string BigInt::to_dec_string() const copy.set_sign(Positive); uint8_t remainder; - std::vector<uint8_t> digits; + secure_vector<uint8_t> digits; + + // (over-)estimate of the number of digits, log2(10) ~= 3.32 + digits.reserve(3.4 * this->bits()); while(copy > 0) { @@ -33,6 +36,9 @@ std::string BigInt::to_dec_string() const std::string s; + if(is_negative()) + s += "-"; + for(auto i = digits.rbegin(); i != digits.rend(); ++i) { s.push_back(*i + '0'); @@ -46,11 +52,17 @@ std::string BigInt::to_dec_string() const std::string BigInt::to_hex_string() const { - const std::vector<uint8_t> bits = BigInt::encode(*this); + std::vector<uint8_t> bits = BigInt::encode(*this); + if(bits.empty()) - return "00"; - else - return hex_encode(bits); + bits.push_back(0); + + std::string hrep; + if(is_negative()) + hrep += "-"; + hrep += "0x"; + hrep += hex_encode(bits); + return hrep; } /* diff --git a/src/lib/math/bigint/big_io.cpp b/src/lib/math/bigint/big_io.cpp index b31315eac..ae2855fcc 100644 --- a/src/lib/math/bigint/big_io.cpp +++ b/src/lib/math/bigint/big_io.cpp @@ -16,17 +16,17 @@ namespace Botan { */ std::ostream& operator<<(std::ostream& stream, const BigInt& n) { - size_t base = 10; - if(stream.flags() & std::ios::hex) - base = 16; - if(stream.flags() & std::ios::oct) + const auto stream_flags = stream.flags(); + if(stream_flags & std::ios::oct) throw Invalid_Argument("Octal output of BigInt not supported"); - if(n == 0) + const size_t base = (stream_flags & std::ios::hex) ? 16 : 10; + + if(n.is_zero()) stream.write("0", 1); else { - if(n < 0) + if(n.is_negative()) stream.write("-", 1); std::string enc; @@ -36,10 +36,7 @@ std::ostream& operator<<(std::ostream& stream, const BigInt& n) else enc = n.to_hex_string(); - size_t skip = 0; - while(skip < enc.size() && enc[skip] == '0') - ++skip; - stream.write(&enc[skip], enc.size() - skip); + stream.write(enc.data(), enc.size()); } if(!stream.good()) throw Stream_IO_Error("BigInt output operator has failed"); |