Esempio n. 1
0
/*
* Get an EME by name
*/
EME* get_eme(const std::string& algo_spec)
   {
   SCAN_Name request(algo_spec);

   Algorithm_Factory& af = global_state().algorithm_factory();

   if(request.algo_name() == "Raw")
      return 0; // No padding

#if defined(BOTAN_HAS_EME_PKCS1v15)
   if(request.algo_name() == "PKCS1v15" && request.arg_count() == 0)
      return new EME_PKCS1v15;
#endif

#if defined(BOTAN_HAS_EME1)
   if(request.algo_name() == "EME1" && request.arg_count_between(1, 2))
      {
      if(request.arg_count() == 1 ||
         (request.arg_count() == 2 && request.arg(1) == "MGF1"))
         {
         return new EME1(af.make_hash_function(request.arg(0)));
         }
      }
#endif

   throw Algorithm_Not_Found(algo_spec);
   }
Esempio n. 2
0
/*************************************************
* Get an allocator                               *
*************************************************/
Allocator* Allocator::get(bool locking)
   {
   std::string type = "";
   if(!locking)
      type = "malloc";

   Allocator* alloc = global_state().get_allocator(type);
   if(alloc)
      return alloc;

   throw Exception("Couldn't find an allocator to use in get_allocator");
   }
Esempio n. 3
0
/*
* Get an EMSA by name
*/
EMSA* get_emsa(const std::string& algo_spec)
   {
   SCAN_Name request(algo_spec);

   Algorithm_Factory& af = global_state().algorithm_factory();

#if defined(BOTAN_HAS_EMSA_RAW)
   if(request.algo_name() == "Raw" && request.arg_count() == 0)
      return new EMSA_Raw;
#endif

#if defined(BOTAN_HAS_EMSA1)
   if(request.algo_name() == "EMSA1" && request.arg_count() == 1)
      return new EMSA1(af.make_hash_function(request.arg(0)));
#endif

#if defined(BOTAN_HAS_EMSA1_BSI)
   if(request.algo_name() == "EMSA1_BSI" && request.arg_count() == 1)
      return new EMSA1_BSI(af.make_hash_function(request.arg(0)));
#endif

#if defined(BOTAN_HAS_EMSA2)
   if(request.algo_name() == "EMSA2" && request.arg_count() == 1)
      return new EMSA2(af.make_hash_function(request.arg(0)));
#endif

#if defined(BOTAN_HAS_EMSA3)
   if(request.algo_name() == "EMSA3" && request.arg_count() == 1)
      {
      if(request.arg(0) == "Raw")
         return new EMSA3_Raw;
      return new EMSA3(af.make_hash_function(request.arg(0)));
      }
#endif

#if defined(BOTAN_HAS_EMSA4)
   if(request.algo_name() == "EMSA4" && request.arg_count_between(1, 3))
      {
      // 3 args: Hash, MGF, salt size (MGF is hardcoded MGF1 in Botan)
      if(request.arg_count() == 1)
         return new EMSA4(af.make_hash_function(request.arg(0)));

      if(request.arg_count() == 2 && request.arg(1) != "MGF1")
         return new EMSA4(af.make_hash_function(request.arg(0)));

      if(request.arg_count() == 3)
         return new EMSA4(af.make_hash_function(request.arg(0)),
                          request.arg_as_u32bit(2, 0));
      }
#endif

   throw Algorithm_Not_Found(algo_spec);
   }
Esempio n. 4
0
/*
* Library Initialization
*/
void LibraryInitializer::initialize(const std::string& arg_string)
   {
   bool thread_safe = false;

   const std::vector<std::string> arg_list = split_on(arg_string, ' ');
   for(u32bit j = 0; j != arg_list.size(); ++j)
      {
      if(arg_list[j].size() == 0)
         continue;

      std::string name, value;

      if(arg_list[j].find('=') == std::string::npos)
         {
         name = arg_list[j];
         value = "true";
         }
      else
         {
         std::vector<std::string> name_and_value = split_on(arg_list[j], '=');
         name = name_and_value[0];
         value = name_and_value[1];
         }

      bool is_on =
         (value == "1" || value == "true" || value == "yes" || value == "on");

      if(name == "thread_safe")
         thread_safe = is_on;
      }

   try
      {
      /*
      This two stage initialization process is because Library_State's
      constructor will implicitly refer to global state through the
      allocators and so for, so global_state() has to be a valid
      reference before initialize() can be called. Yeah, gross.
      */
      set_global_state(new Library_State);

      global_state().initialize(thread_safe);
      }
   catch(...)
      {
      deinitialize();
      throw;
      }
   }
Esempio n. 5
0
/*************************************************
* Library Initialization                         *
*************************************************/
void LibraryInitializer::initialize(const InitializerOptions& args,
                                    Modules& modules)
   {
   try
      {
      set_global_state(new Library_State);

      global_state().initialize(args, modules);
      }
   catch(...)
      {
      deinitialize();
      throw;
      }
   }
Esempio n. 6
0
/*
* Decode PKCS#5 PBES2 parameters
*/
void PBE_PKCS5v20::decode_params(DataSource& source)
   {
   AlgorithmIdentifier kdf_algo, enc_algo;

   BER_Decoder(source)
      .start_cons(SEQUENCE)
         .decode(kdf_algo)
         .decode(enc_algo)
         .verify_end()
      .end_cons();

   if(kdf_algo.oid == OIDS::lookup("PKCS5.PBKDF2"))
      {
      BER_Decoder(kdf_algo.parameters)
         .start_cons(SEQUENCE)
            .decode(salt, OCTET_STRING)
            .decode(iterations)
            .decode_optional(key_length, INTEGER, UNIVERSAL)
            .verify_end()
         .end_cons();
      }
   else
      throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " +
                           kdf_algo.oid.as_string());

   Algorithm_Factory& af = global_state().algorithm_factory();

   std::string cipher = OIDS::lookup(enc_algo.oid);
   std::vector<std::string> cipher_spec = split_on(cipher, '/');
   if(cipher_spec.size() != 2)
      throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher);

   if(!known_cipher(cipher_spec[0]) || cipher_spec[1] != "CBC")
      throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " +
                           cipher);

   BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end();

   block_cipher = af.make_block_cipher(cipher_spec[0]);
   hash_function = af.make_hash_function("SHA-160");

   if(key_length == 0)
      key_length = block_cipher->maximum_keylength();

   if(salt.size() < 8)
      throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small");
   }
Esempio n. 7
0
BigInt compute_x(const std::string& hash_id,
                 const std::string& identifier,
                 const std::string& password,
                 const MemoryRegion<byte>& salt)
   {
   std::auto_ptr<HashFunction> hash_fn(
      global_state().algorithm_factory().make_hash_function(hash_id));

   hash_fn->update(identifier);
   hash_fn->update(":");
   hash_fn->update(password);

   SecureVector<byte> inner_h = hash_fn->final();

   hash_fn->update(salt);
   hash_fn->update(inner_h);

   SecureVector<byte> outer_h = hash_fn->final();

   return BigInt::decode(outer_h);
   }
Esempio n. 8
0
/*
* Get a S2K algorithm by name
*/
S2K* get_s2k(const std::string& algo_spec)
   {
   SCAN_Name request(algo_spec);

   Algorithm_Factory& af = global_state().algorithm_factory();

#if defined(BOTAN_HAS_PBKDF1)
   if(request.algo_name() == "PBKDF1" && request.arg_count() == 1)
      return new PKCS5_PBKDF1(af.make_hash_function(request.arg(0)));
#endif

#if defined(BOTAN_HAS_PBKDF2)
   if(request.algo_name() == "PBKDF2" && request.arg_count() == 1)
      return new PKCS5_PBKDF2(new HMAC(af.make_hash_function(request.arg(0))));
#endif

#if defined(BOTAN_HAS_PGPS2K)
   if(request.algo_name() == "OpenPGP-S2K" && request.arg_count() == 1)
      return new OpenPGP_S2K(af.make_hash_function(request.arg(0)));
#endif

   throw Algorithm_Not_Found(algo_spec);
   }
Esempio n. 9
0
/*
* Get an KDF by name
*/
KDF* get_kdf(const std::string& algo_spec)
   {
   SCAN_Name request(algo_spec);

   Algorithm_Factory& af = global_state().algorithm_factory();

   if(request.algo_name() == "Raw")
      return 0; // No KDF

#if defined(BOTAN_HAS_KDF1)
   if(request.algo_name() == "KDF1" && request.arg_count() == 1)
      return new KDF1(af.make_hash_function(request.arg(0)));
#endif

#if defined(BOTAN_HAS_KDF2)
   if(request.algo_name() == "KDF2" && request.arg_count() == 1)
      return new KDF2(af.make_hash_function(request.arg(0)));
#endif

#if defined(BOTAN_HAS_X942_PRF)
   if(request.algo_name() == "X9.42-PRF" && request.arg_count() == 1)
      return new X942_PRF(request.arg(0)); // OID
#endif

#if defined(BOTAN_HAS_TLS_V10_PRF)
   if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0)
      return new TLS_PRF;
#endif

#if defined(BOTAN_HAS_SSL_V3_PRF)
   if(request.algo_name() == "SSL3-PRF" && request.arg_count() == 0)
      return new SSL3_PRF;
#endif

   throw Algorithm_Not_Found(algo_spec);
   }
Esempio n. 10
0
/*************************************************
* Pooling_Allocator Constructor                  *
*************************************************/
Pooling_Allocator::Pooling_Allocator(u32bit p_size, bool) :
   PREF_SIZE(choose_pref_size(p_size))
   {
   mutex = global_state().get_mutex();
   last_used = blocks.begin();
   }
Esempio n. 11
0
std::string transcode(const std::string& str,
                      Character_Set to, Character_Set from)
   {
   return global_state().transcode(str, to, from);
   }
Esempio n. 12
0
SCAN_Name::SCAN_Name(std::string algo_spec)
   {
   orig_algo_spec = algo_spec;

   std::vector<std::pair<size_t, std::string> > name;
   size_t level = 0;
   std::pair<size_t, std::string> accum = std::make_pair(level, "");

   std::string decoding_error = "Bad SCAN name '" + algo_spec + "': ";

   algo_spec = global_state().deref_alias(algo_spec);

   for(size_t i = 0; i != algo_spec.size(); ++i)
      {
      char c = algo_spec[i];

      if(c == '/' || c == ',' || c == '(' || c == ')')
         {
         if(c == '(')
            ++level;
         else if(c == ')')
            {
            if(level == 0)
               throw Decoding_Error(decoding_error + "Mismatched parens");
            --level;
            }

         if(c == '/' && level > 0)
            accum.second.push_back(c);
         else
            {
            if(accum.second != "")
               name.push_back(deref_aliases(accum));
            accum = std::make_pair(level, "");
            }
         }
      else
         accum.second.push_back(c);
      }

   if(accum.second != "")
      name.push_back(deref_aliases(accum));

   if(level != 0)
      throw Decoding_Error(decoding_error + "Missing close paren");

   if(name.size() == 0)
      throw Decoding_Error(decoding_error + "Empty name");

   alg_name = name[0].second;

   bool in_modes = false;

   for(size_t i = 1; i != name.size(); ++i)
      {
      if(name[i].first == 0)
         {
         mode_info.push_back(make_arg(name, i));
         in_modes = true;
         }
      else if(name[i].first == 1 && !in_modes)
         args.push_back(make_arg(name, i));
      }
   }
Esempio n. 13
0
DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh) :
   p(dh.group_p()), powermod_x_p(dh.get_x(), p)
   {
   BigInt k(global_state().global_rng(), p.bits() - 1);
   blinder = Blinder(k, powermod_x_p(inverse_mod(k, p)), p);
   }