Example #1
0
/*
* Encode two BigInt, with leading 0s if needed, and concatenate
*/
secure_vector<uint8_t> BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes)
   {
   if(n1.bytes() > bytes || n2.bytes() > bytes)
      throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly");
   secure_vector<uint8_t> output(2 * bytes);
   n1.binary_encode(output.data()        , bytes);
   n2.binary_encode(output.data() + bytes, bytes);
   return output;
   }
Example #2
0
/*
* Default ElGamal Encrypt Operation
*/
SecureVector<byte> Default_ELG_Op::encrypt(const byte in[], u32bit length,
                                           const BigInt& k) const
   {
   BigInt m(in, length);
   if(m >= p)
      throw Invalid_Argument("Default_ELG_Op::encrypt: Input is too large");

   BigInt a = powermod_g_p(k);
   BigInt b = mod_p.multiply(m, powermod_y_p(k));

   SecureVector<byte> output(2*p.bytes());
   a.binary_encode(output + (p.bytes() - a.bytes()));
   b.binary_encode(output + output.size() / 2 + (p.bytes() - b.bytes()));
   return output;
   }
Example #3
0
//static
void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n)
   {
   if(n.bytes() > bytes)
      throw Encoding_Error("encode_1363: n is too large to encode properly");

   n.binary_encode(output, bytes);
   }
Example #4
0
SecureVector<byte>
DSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
                              RandomNumberGenerator& rng)
   {
   rng.add_entropy(msg, msg_len);

   BigInt i(msg, msg_len);
   BigInt r = 0, s = 0;

   while(r == 0 || s == 0)
      {
      BigInt k;
      do
         k.randomize(rng, q.bits());
      while(k >= q);

      r = mod_q.reduce(powermod_g_p(k));
      s = mod_q.multiply(inverse_mod(k, q), mul_add(x, r, i));
      }

   SecureVector<byte> output(2*q.bytes());
   r.binary_encode(&output[output.size() / 2 - r.bytes()]);
   s.binary_encode(&output[output.size() - s.bytes()]);
   return output;
   }
Example #5
0
SecureVector<byte>
ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
                                RandomNumberGenerator& rng)
   {
   rng.add_entropy(msg, msg_len);

   BigInt m(msg, msg_len);

   BigInt r = 0, s = 0;

   while(r == 0 || s == 0)
      {
      // This contortion is necessary for the tests
      BigInt k;
      k.randomize(rng, order.bits());

      while(k >= order)
         k.randomize(rng, order.bits() - 1);

      PointGFp k_times_P = base_point * k;
      r = mod_order.reduce(k_times_P.get_affine_x());
      s = mod_order.multiply(inverse_mod(k, order), mul_add(x, r, m));
      }

   SecureVector<byte> output(2*order.bytes());
   r.binary_encode(&output[output.size() / 2 - r.bytes()]);
   s.binary_encode(&output[output.size() - s.bytes()]);
   return output;
   }
Example #6
0
/*
* Encode a BigInt, with leading 0s if needed
*/
secure_vector<uint8_t> BigInt::encode_1363(const BigInt& n, size_t bytes)
   {
   if(n.bytes() > bytes)
      throw Encoding_Error("encode_1363: n is too large to encode properly");

   secure_vector<uint8_t> output(bytes);
   n.binary_encode(output.data(), output.size());
   return output;
   }
Example #7
0
std::vector<byte> GOST_3410_PublicKey::x509_subject_public_key() const
   {
   const BigInt x = public_point().get_affine_x();
   const BigInt y = public_point().get_affine_y();

   size_t part_size = std::max(x.bytes(), y.bytes());

   std::vector<byte> bits(2*part_size);

   x.binary_encode(&bits[part_size - x.bytes()]);
   y.binary_encode(&bits[2*part_size - y.bytes()]);

   // Keys are stored in little endian format (WTF)
   for(size_t i = 0; i != part_size / 2; ++i)
      {
      std::swap(bits[i], bits[part_size-1-i]);
      std::swap(bits[part_size+i], bits[2*part_size-1-i]);
      }

   return DER_Encoder().encode(bits, OCTET_STRING).get_contents_unlocked();
   }
Example #8
0
/*************************************************
* Encode a BigInt, with leading 0s if needed     *
*************************************************/
SecureVector<byte> BigInt::encode_1363(const BigInt& n, u32bit bytes)
   {
   const u32bit n_bytes = n.bytes();
   if(n_bytes > bytes)
      throw Encoding_Error("encode_1363: n is too large to encode properly");

   const u32bit leading_0s = bytes - n_bytes;

   SecureVector<byte> output(bytes);
   encode(output + leading_0s, n, Binary);
   return output;
   }
Example #9
0
bool SshEncryptionFacility::createAuthenticationKeyFromPKCS8(const QByteArray &privKeyFileContents,
    QList<BigInt> &pubKeyParams, QList<BigInt> &allKeyParams, QString &error)
{
    try {
        Pipe pipe;
        pipe.process_msg(convertByteArray(privKeyFileContents), privKeyFileContents.size());
        m_authKey.reset(PKCS8::load_key(pipe, m_rng, SshKeyPasswordRetriever()));
        if (auto * const dsaKey = dynamic_cast<DSA_PrivateKey *>(m_authKey.data())) {
            m_authKeyAlgoName = SshCapabilities::PubKeyDss;
            pubKeyParams << dsaKey->group_p() << dsaKey->group_q()
                         << dsaKey->group_g() << dsaKey->get_y();
            allKeyParams << pubKeyParams << dsaKey->get_x();
        } else if (auto * const rsaKey = dynamic_cast<RSA_PrivateKey *>(m_authKey.data())) {
            m_authKeyAlgoName = SshCapabilities::PubKeyRsa;
            pubKeyParams << rsaKey->get_e() << rsaKey->get_n();
            allKeyParams << pubKeyParams << rsaKey->get_p() << rsaKey->get_q()
                         << rsaKey->get_d();
        } else if (auto * const ecdsaKey = dynamic_cast<ECDSA_PrivateKey *>(m_authKey.data())) {
            const BigInt value = ecdsaKey->private_value();
            m_authKeyAlgoName = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth(
                        static_cast<int>(value.bytes()));
            pubKeyParams << ecdsaKey->public_point().get_affine_x()
                         << ecdsaKey->public_point().get_affine_y();
            allKeyParams << pubKeyParams << value;
        } else {
            qCWarning(sshLog, "%s: Unexpected code flow, expected success or exception.",
                      Q_FUNC_INFO);
            return false;
        }
    } catch (const Exception &ex) {
        error = QLatin1String(ex.what());
        return false;
    } catch (const Decoding_Error &ex) {
        error = QLatin1String(ex.what());
        return false;
    }

    return true;
}
Example #10
0
#include "catchy_tests.h"

#if defined(BOTAN_HAS_BIGINT)

#include <botan/bigint.h>

using namespace Botan;

TEST_CASE("Bigint basics", "[bigint]")
   {
   SECTION("in 0-bit border")
      {
      BigInt a(0u);
      CHECK_THAT(a.bits(),      Equals(0));
      CHECK_THAT(a.bytes(),     Equals(0));
      CHECK_THAT(a.to_u32bit(), Equals(0));
      }
   SECTION("above 0-bit border")
      {
      BigInt a(1u);
      CHECK_THAT(a.bits(),      Equals(1));
      CHECK_THAT(a.bytes(),     Equals(1));
      CHECK_THAT(a.to_u32bit(), Equals(1));
      }
   SECTION("in 8-bit border")
      {
      BigInt a(255u);
      CHECK_THAT(a.bits(),      Equals(8));
      CHECK_THAT(a.bytes(),     Equals(1));
      CHECK_THAT(a.to_u32bit(), Equals(255));
Example #11
0
bool SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray &privKeyFileContents,
    QList<BigInt> &pubKeyParams, QList<BigInt> &allKeyParams, QString &error)
{
    try {
        bool syntaxOk = true;
        QList<QByteArray> lines = privKeyFileContents.split('\n');
        while (lines.last().isEmpty())
            lines.removeLast();
        if (lines.count() < 3) {
            syntaxOk = false;
        } else if (lines.first() == PrivKeyFileStartLineRsa) {
            if (lines.last() != PrivKeyFileEndLineRsa)
                syntaxOk = false;
            else
                m_authKeyAlgoName = SshCapabilities::PubKeyRsa;
        } else if (lines.first() == PrivKeyFileStartLineDsa) {
            if (lines.last() != PrivKeyFileEndLineDsa)
                syntaxOk = false;
            else
                m_authKeyAlgoName = SshCapabilities::PubKeyDss;
        } else if (lines.first() == PrivKeyFileStartLineEcdsa) {
            if (lines.last() != PrivKeyFileEndLineEcdsa)
                syntaxOk = false;
            // m_authKeyAlgoName set below, as we don't know the size yet.
        } else {
            syntaxOk = false;
        }
        if (!syntaxOk) {
            error = SSH_TR("Unexpected format.");
            return false;
        }

        QByteArray privateKeyBlob;
        for (int i = 1; i < lines.size() - 1; ++i)
            privateKeyBlob += lines.at(i);
        privateKeyBlob = QByteArray::fromBase64(privateKeyBlob);

        BER_Decoder decoder(convertByteArray(privateKeyBlob), privateKeyBlob.size());
        BER_Decoder sequence = decoder.start_cons(SEQUENCE);
        size_t version;
        sequence.decode (version);
        const size_t expectedVersion = m_authKeyAlgoName.isEmpty() ? 1 : 0;
        if (version != expectedVersion) {
            error = SSH_TR("Key encoding has version %1, expected %2.")
                    .arg(version).arg(expectedVersion);
            return false;
        }

        if (m_authKeyAlgoName == SshCapabilities::PubKeyDss) {
            BigInt p, q, g, y, x;
            sequence.decode (p).decode (q).decode (g).decode (y).decode (x);
            DSA_PrivateKey * const dsaKey = new DSA_PrivateKey(m_rng, DL_Group(p, q, g), x);
            m_authKey.reset(dsaKey);
            pubKeyParams << p << q << g << y;
            allKeyParams << pubKeyParams << x;
        } else if (m_authKeyAlgoName == SshCapabilities::PubKeyRsa) {
            BigInt p, q, e, d, n;
            sequence.decode(n).decode(e).decode(d).decode(p).decode(q);
            RSA_PrivateKey * const rsaKey = new RSA_PrivateKey(m_rng, p, q, e, d, n);
            m_authKey.reset(rsaKey);
            pubKeyParams << e << n;
            allKeyParams << pubKeyParams << p << q << d;
        } else {
            BigInt privKey;
            sequence.decode_octet_string_bigint(privKey);
            m_authKeyAlgoName = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth(
                        static_cast<int>(privKey.bytes()));
            const EC_Group group(SshCapabilities::oid(m_authKeyAlgoName));
            auto * const key = new ECDSA_PrivateKey(m_rng, group, privKey);
            m_authKey.reset(key);
            pubKeyParams << key->public_point().get_affine_x()
                         << key->public_point().get_affine_y();
            allKeyParams << pubKeyParams << privKey;
        }

        sequence.discard_remaining();
        sequence.verify_end();
    } catch (const Exception &ex) {
        error = QLatin1String(ex.what());
        return false;
    } catch (const Decoding_Error &ex) {
        error = QLatin1String(ex.what());
        return false;
    }
    return true;
}