示例#1
0
/*
* Parse an ASN.1 OID string
*/
std::vector<u32bit> parse_asn1_oid(const std::string& oid)
   {
   std::string substring;
   std::vector<u32bit> oid_elems;

   for(auto i = oid.begin(); i != oid.end(); ++i)
      {
      char c = *i;

      if(c == '.')
         {
         if(substring.empty())
            throw Invalid_OID(oid);
         oid_elems.push_back(to_u32bit(substring));
         substring.clear();
         }
      else
         substring += c;
      }

   if(substring.empty())
      throw Invalid_OID(oid);
   oid_elems.push_back(to_u32bit(substring));

   if(oid_elems.size() < 2)
      throw Invalid_OID(oid);

   return oid_elems;
   }
示例#2
0
/*************************************************
* Parse an ASN.1 OID string                      *
*************************************************/
std::vector<u32bit> parse_asn1_oid(const std::string& oid)
   {
   std::string substring;
   std::vector<u32bit> oid_elems;

   for(std::string::const_iterator j = oid.begin(); j != oid.end(); ++j)
      {
      char c = *j;

      if(c == '.')
         {
         if(substring == "")
            throw Invalid_OID(oid);
         oid_elems.push_back(to_u32bit(substring));
         substring.clear();
         }
      else
         substring += c;
      }

   if(substring == "")
      throw Invalid_OID(oid);
   oid_elems.push_back(to_u32bit(substring));

   if(oid_elems.size() < 2)
      throw Invalid_OID(oid);

   return oid_elems;
   }
示例#3
0
/*
* Set the time with a human readable string
*/
void EAC_Time::set_to(const std::string& time_str)
   {
   if(time_str == "")
      {
      year = month = day = 0;
      return;
      }

   std::vector<std::string> params;
   std::string current;

   for(u32bit j = 0; j != time_str.size(); ++j)
      {
      if(Charset::is_digit(time_str[j]))
         current += time_str[j];
      else
         {
         if(current != "")
            params.push_back(current);
         current.clear();
         }
      }
   if(current != "")
      params.push_back(current);

   if(params.size() != 3)
      throw Invalid_Argument("Invalid time specification " + time_str);

   year   = to_u32bit(params[0]);
   month  = to_u32bit(params[1]);
   day    = to_u32bit(params[2]);

   if(!passes_sanity_check())
      throw Invalid_Argument("Invalid time specification " + time_str);
   }
示例#4
0
/*************************************************
* Convert a string into a time duration          *
*************************************************/
u32bit timespec_to_u32bit(const std::string& timespec)
   {
   if(timespec == "")
      return 0;

   const char suffix = timespec[timespec.size()-1];
   std::string value = timespec.substr(0, timespec.size()-1);

   u32bit scale = 1;

   if(Charset::is_digit(suffix))
      value += suffix;
   else if(suffix == 's')
      scale = 1;
   else if(suffix == 'm')
      scale = 60;
   else if(suffix == 'h')
      scale = 60 * 60;
   else if(suffix == 'd')
      scale = 24 * 60 * 60;
   else if(suffix == 'y')
      scale = 365 * 24 * 60 * 60;
   else
      throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec);

   return scale * to_u32bit(value);
   }
示例#5
0
/*
* Get a single u32bit atom
*/
u32bit Data_Store::get1_u32bit(const std::string& key,
                               u32bit default_val) const
   {
   std::vector<std::string> vals = get(key);

   if(vals.empty())
      return default_val;
   else if(vals.size() > 1)
      throw Invalid_State("Data_Store::get1_u32bit: Multiple values for " +
                          key);

   return to_u32bit(vals[0]);
   }
示例#6
0
bool check_bcrypt(const std::string& pass, const std::string& hash)
   {
   if(hash.size() != 60 ||
      hash[0] != '$' || hash[1] != '2' || hash[2] != 'a' ||
      hash[3] != '$' || hash[6] != '$')
      {
      return false;
      }

   const u16bit workfactor = to_u32bit(hash.substr(4, 2));

   const std::vector<byte> salt = bcrypt_base64_decode(hash.substr(7, 22));
   if(salt.size() != 16)
      return false;

   const std::string compare = make_bcrypt(pass, salt, workfactor);

   return same_mem(hash.data(), compare.data(), compare.size());
   }
示例#7
0
/*************************************************
* Convert a decimal-dotted string to binary IP   *
*************************************************/
u32bit string_to_ipv4(const std::string& str)
   {
   std::vector<std::string> parts = split_on(str, '.');

   if(parts.size() != 4)
      throw Decoding_Error("Invalid IP string " + str);

   u32bit ip = 0;

   for(size_t j = 0; j != parts.size(); j++)
      {
      u32bit octet = to_u32bit(parts[j]);

      if(octet > 255)
         throw Decoding_Error("Invalid IP string " + str);

      ip = (ip << 8) | (octet & 0xFF);
      }

   return ip;
   }
示例#8
0
/*
* Convert a decimal-dotted string to binary IP
*/
u32bit string_to_ipv4(const std::string& str)
   {
   std::vector<std::string> parts = split_on(str, '.');

   if(parts.size() != 4)
      throw Decoding_Error("Invalid IP string " + str);

   u32bit ip = 0;

   for(auto part = parts.begin(); part != parts.end(); ++part)
      {
      u32bit octet = to_u32bit(*part);

      if(octet > 255)
         throw Decoding_Error("Invalid IP string " + str);

      ip = (ip << 8) | (octet & 0xFF);
      }

   return ip;
   }
示例#9
0
size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const
   {
   if(i >= arg_count())
      return def_value;
   return to_u32bit(args[i]);
   }
示例#10
0
std::unique_ptr<Private_Key>
create_private_key(const std::string& alg_name,
                   RandomNumberGenerator& rng,
                   const std::string& params,
                   const std::string& provider)
   {
   /*
   * Default paramaters are chosen for work factor > 2**128 where possible
   */

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
#endif

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      {
      const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
#if defined(BOTAN_HAS_OPENSSL)
      if(provider.empty() || provider == "openssl")
         {
         std::unique_ptr<Botan::Private_Key> pk;
         if((pk = make_openssl_rsa_private_key(rng, rsa_bits)))
            return pk;

         if(!provider.empty())
            return nullptr;
         }
#endif
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
      }
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      {
      std::vector<std::string> mce_param =
         Botan::split_on(params.empty() ? "2960,57" : params, ',');

      if(mce_param.size() != 2)
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);

      size_t mce_n = Botan::to_u32bit(mce_param[0]);
      size_t mce_t = Botan::to_u32bit(mce_param[1]);

      return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
      }
#endif

#if defined(BOTAN_HAS_XMSS)
   if(alg_name == "XMSS")
      {
      return std::unique_ptr<Private_Key>(
         new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS_SHA2-512_W16_H10" : params).oid(), rng));
      }
#endif

#if defined(BOTAN_HAS_ED25519)
   if(alg_name == "Ed25519")
      {
      return std::unique_ptr<Private_Key>(new Ed25519_PrivateKey(rng));
      }
#endif

   // ECC crypto
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)

   if(alg_name == "ECDSA" ||
      alg_name == "ECDH" ||
      alg_name == "ECKCDSA" ||
      alg_name == "ECGDSA" ||
      alg_name == "SM2" ||
      alg_name == "SM2_Sig" ||
      alg_name == "SM2_Enc" ||
      alg_name == "GOST-34.10")
      {
      const EC_Group ec_group(params.empty() ? default_ec_group_for(alg_name) : params);

#if defined(BOTAN_HAS_ECDSA)
      if(alg_name == "ECDSA")
         return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECDH)
      if(alg_name == "ECDH")
         return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
      if(alg_name == "ECKCDSA")
         return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
      if(alg_name == "GOST-34.10")
         return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_SM2)
      if(alg_name == "SM2" || alg_name == "SM2_Sig" || alg_name == "SM2_Enc")
         return std::unique_ptr<Private_Key>(new SM2_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECGDSA)
      if(alg_name == "ECGDSA")
         return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
#endif
      }
#endif

   // DL crypto
#if defined(BOTAN_HAS_DL_GROUP)
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
      {
      std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
      DL_Group modp_group(params.empty() ? default_group : params);

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
      if(alg_name == "DH")
         return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
#endif

#if defined(BOTAN_HAS_DSA)
      if(alg_name == "DSA")
         return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
      if(alg_name == "ElGamal")
         return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
#endif
      }
#endif

   BOTAN_UNUSED(alg_name, rng, params, provider);

   return std::unique_ptr<Private_Key>();
   }
示例#11
0
void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag)
   {
   if(spec_tag == UTC_OR_GENERALIZED_TIME)
      {
      try
         {
         set_to(t_spec, GENERALIZED_TIME);
         return;
         }
      catch(Invalid_Argument&) {} // Not a generalized time. Continue

      try
         {
         set_to(t_spec, UTC_TIME);
         return;
         }
      catch(Invalid_Argument&) {} // Not a UTC time. Continue

      throw Invalid_Argument("Time string could not be parsed as GeneralizedTime or UTCTime.");
      }

   BOTAN_ASSERT(spec_tag == UTC_TIME || spec_tag == GENERALIZED_TIME, "Invalid tag.");

   if(t_spec.empty())
      throw Invalid_Argument("Time string must not be empty.");

   if(t_spec.back() != 'Z')
      throw Unsupported_Argument("Botan does not support times with timezones other than Z: " + t_spec);

   if(spec_tag == GENERALIZED_TIME)
      {
      if(t_spec.size() != 15)
         throw Invalid_Argument("Invalid GeneralizedTime string: '" + t_spec + "'");
      }
   else if(spec_tag == UTC_TIME)
      {
      if(t_spec.size() != 13)
         throw Invalid_Argument("Invalid UTCTime string: '" + t_spec + "'");
      }

   const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4;

   std::vector<std::string> params;
   std::string current;

   for(size_t j = 0; j != YEAR_SIZE; ++j)
      current += t_spec[j];
   params.push_back(current);
   current.clear();

   for(size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j)
      {
      current += t_spec[j];
      if(current.size() == 2)
         {
         params.push_back(current);
         current.clear();
         }
      }

   m_year   = to_u32bit(params[0]);
   m_month  = to_u32bit(params[1]);
   m_day    = to_u32bit(params[2]);
   m_hour   = to_u32bit(params[3]);
   m_minute = to_u32bit(params[4]);
   m_second = (params.size() == 6) ? to_u32bit(params[5]) : 0;
   m_tag    = spec_tag;

   if(spec_tag == UTC_TIME)
      {
      if(m_year >= 50) m_year += 1900;
      else             m_year += 2000;
      }

   if(!passes_sanity_check())
      throw Invalid_Argument("Time did not pass sanity check: " + t_spec);
   }
示例#12
0
文件: http_util.cpp 项目: louiz/botan
Response http_sync(http_exch_fn http_transact,
                   const std::string& verb,
                   const std::string& url,
                   const std::string& content_type,
                   const std::vector<byte>& body,
                   size_t allowable_redirects)
{
    if(url.empty())
        throw HTTP_Error("URL empty");

    const auto protocol_host_sep = url.find("://");
    if(protocol_host_sep == std::string::npos)
        throw HTTP_Error("Invalid URL '" + url + "'");

    const auto host_loc_sep = url.find('/', protocol_host_sep + 3);

    std::string hostname, loc;

    if(host_loc_sep == std::string::npos)
    {
        hostname = url.substr(protocol_host_sep + 3, std::string::npos);
        loc = "/";
    }
    else
    {
        hostname = url.substr(protocol_host_sep + 3, host_loc_sep-protocol_host_sep-3);
        loc = url.substr(host_loc_sep, std::string::npos);
    }

    std::ostringstream outbuf;

    outbuf << verb << " " << loc << " HTTP/1.0\r\n";
    outbuf << "Host: " << hostname << "\r\n";

    if(verb == "GET")
    {
        outbuf << "Accept: */*\r\n";
        outbuf << "Cache-Control: no-cache\r\n";
    }
    else if(verb == "POST")
        outbuf << "Content-Length: " << body.size() << "\r\n";

    if(!content_type.empty())
        outbuf << "Content-Type: " << content_type << "\r\n";
    outbuf << "Connection: close\r\n\r\n";
    outbuf.write(reinterpret_cast<const char*>(body.data()), body.size());

    std::istringstream io(http_transact(hostname, outbuf.str()));

    std::string line1;
    std::getline(io, line1);
    if(!io || line1.empty())
        throw HTTP_Error("No response");

    std::stringstream response_stream(line1);
    std::string http_version;
    unsigned int status_code;
    std::string status_message;

    response_stream >> http_version >> status_code;

    std::getline(response_stream, status_message);

    if(!response_stream || http_version.substr(0,5) != "HTTP/")
        throw HTTP_Error("Not an HTTP response");

    std::map<std::string, std::string> headers;
    std::string header_line;
    while (std::getline(io, header_line) && header_line != "\r")
    {
        auto sep = header_line.find(": ");
        if(sep == std::string::npos || sep > header_line.size() - 2)
            throw HTTP_Error("Invalid HTTP header " + header_line);
        const std::string key = header_line.substr(0, sep);

        if(sep + 2 < header_line.size() - 1)
        {
            const std::string val = header_line.substr(sep + 2, (header_line.size() - 1) - (sep + 2));
            headers[key] = val;
        }
    }

    if(status_code == 301 && headers.count("Location"))
    {
        if(allowable_redirects == 0)
            throw HTTP_Error("HTTP redirection count exceeded");
        return GET_sync(headers["Location"], allowable_redirects - 1);
    }

    std::vector<byte> resp_body;
    std::vector<byte> buf(4096);
    while(io.good())
    {
        io.read(reinterpret_cast<char*>(buf.data()), buf.size());
        resp_body.insert(resp_body.end(), buf.data(), &buf[io.gcount()]);
    }

    const std::string header_size = search_map(headers, std::string("Content-Length"));

    if(!header_size.empty())
    {
        if(resp_body.size() != to_u32bit(header_size))
            throw HTTP_Error("Content-Length disagreement, header says " +
                             header_size + " got " + std::to_string(resp_body.size()));
    }

    return Response(status_code, status_message, resp_body, headers);
}