Exemplo n.º 1
0
GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id,
                                         const secure_vector<byte>& key_bits)
   {
   OID ecc_param_id;

   // The parameters also includes hash and cipher OIDs
   BER_Decoder(alg_id.parameters).start_cons(SEQUENCE).decode(ecc_param_id);

   domain_params = EC_Group(ecc_param_id);

   secure_vector<byte> bits;
   BER_Decoder(key_bits).decode(bits, OCTET_STRING);

   const size_t part_size = bits.size() / 2;

   // 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]);
      }

   BigInt x(bits.data(), part_size);
   BigInt y(&bits[part_size], part_size);

   public_key = PointGFp(domain().get_curve(), x, y);

   BOTAN_ASSERT(public_key.on_the_curve(),
                "Loaded GOST 34.10 public key is on the curve");
   }
Exemplo n.º 2
0
Response::Response(const uint8_t response_bits[], size_t response_bits_len) :
   m_response_bits(response_bits, response_bits + response_bits_len)
   {
   m_dummy_response_status = Certificate_Status_Code::OCSP_RESPONSE_INVALID;

   BER_Decoder response_outer = BER_Decoder(m_response_bits).start_cons(SEQUENCE);

   size_t resp_status = 0;

   response_outer.decode(resp_status, ENUMERATED, UNIVERSAL);

   if(resp_status != 0)
      throw Exception("OCSP response status " + std::to_string(resp_status));

   if(response_outer.more_items())
      {
      BER_Decoder response_bytes =
         response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE);

      response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"),
                                      "Unknown response type in OCSP response");

      BER_Decoder basicresponse =
         BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE);

      basicresponse.start_cons(SEQUENCE)
           .raw_bytes(m_tbs_bits)
         .end_cons()
         .decode(m_sig_algo)
         .decode(m_signature, BIT_STRING);
      decode_optional_list(basicresponse, ASN1_Tag(0), m_certs);

      size_t responsedata_version = 0;
      Extensions extensions;

      BER_Decoder(m_tbs_bits)
         .decode_optional(responsedata_version, ASN1_Tag(0),
                          ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))

         .decode_optional(m_signer_name, ASN1_Tag(1),
                          ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))

         .decode_optional_string(m_key_hash, OCTET_STRING, 2,
                                 ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))

         .decode(m_produced_at)

         .decode_list(m_responses)

         .decode_optional(extensions, ASN1_Tag(1),
                          ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
      }

   response_outer.end_cons();
   }
Exemplo n.º 3
0
void EAC1_1_ADO::decode_info(DataSource& source,
                             SecureVector<byte> & res_tbs_bits,
                             ECDSA_Signature & res_sig)
   {
   SecureVector<byte> concat_sig;
   SecureVector<byte> cert_inner_bits;
   ASN1_Car car;

   BER_Decoder(source)
      .start_cons(ASN1_Tag(7))
      .start_cons(ASN1_Tag(33))
      .raw_bytes(cert_inner_bits)
      .end_cons()
      .decode(car)
      .decode(concat_sig, OCTET_STRING, ASN1_Tag(55), APPLICATION)
      .end_cons();

   SecureVector<byte> enc_cert = DER_Encoder()
      .start_cons(ASN1_Tag(33), APPLICATION)
      .raw_bytes(cert_inner_bits)
      .end_cons()
      .get_contents();

   res_tbs_bits = enc_cert;
   res_tbs_bits += DER_Encoder().encode(car).get_contents();
   res_sig = decode_concatenation(concat_sig);
   }
Exemplo n.º 4
0
EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
                             const secure_vector<byte>& key_bits)
   {
   m_domain_params = EC_Group(alg_id.parameters);
   m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;

   OID key_parameters;
   secure_vector<byte> public_key_bits;

   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
         .decode_and_check<size_t>(1, "Unknown version code for ECC key")
         .decode_octet_string_bigint(m_private_key)
         .decode_optional(key_parameters, ASN1_Tag(0), PRIVATE)
         .decode_optional_string(public_key_bits, BIT_STRING, 1, PRIVATE)
      .end_cons();

   if(!key_parameters.empty() && key_parameters != alg_id.oid)
      throw Decoding_Error("EC_PrivateKey - inner and outer OIDs did not match");

   if(public_key_bits.empty())
      {
      m_public_key = domain().get_base_point() * m_private_key;

      BOTAN_ASSERT(m_public_key.on_the_curve(),
                   "Public point derived from loaded key was on the curve");
      }
   else
      {
      m_public_key = OS2ECP(public_key_bits, domain().get_curve());
      // OS2ECP verifies that the point is on the curve
      }
   }
Exemplo n.º 5
0
DL_Scheme_PublicKey::DL_Scheme_PublicKey(const AlgorithmIdentifier& alg_id,
                                         const std::vector<uint8_t>& key_bits,
                                         DL_Group::Format format) :
   m_group(alg_id.get_parameters(), format)
   {
   BER_Decoder(key_bits).decode(m_y);
   }
Exemplo 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");
   }
Exemplo n.º 7
0
DL_Scheme_PrivateKey::DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id,
                                           const secure_vector<uint8_t>& key_bits,
                                           DL_Group::Format format)
   {
   m_group.BER_decode(alg_id.get_parameters(), format);

   BER_Decoder(key_bits).decode(m_x);
   }
Exemplo n.º 8
0
PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
   : Object(session, props)
   {
   m_domain_params = EC_Group(props.ec_params());

   secure_vector<uint8_t> ec_point;
   BER_Decoder(props.ec_point()).decode(ec_point, OCTET_STRING);
   m_public_key = OS2ECP(ec_point, m_domain_params.get_curve());
   m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
   }
Exemplo n.º 9
0
EC_Group::EC_Group(const std::vector<uint8_t>& ber_data)
   {
   BER_Decoder ber(ber_data);
   BER_Object obj = ber.get_next_object();

   if(obj.type_tag == NULL_TAG)
      throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters");
   else if(obj.type_tag == OBJECT_ID)
      {
      OID dom_par_oid;
      BER_Decoder(ber_data).decode(dom_par_oid);
      *this = EC_Group(dom_par_oid);
      }
   else if(obj.type_tag == SEQUENCE)
      {
      BigInt p, a, b;
      std::vector<uint8_t> sv_base_point;

      BER_Decoder(ber_data)
         .start_cons(SEQUENCE)
           .decode_and_check<size_t>(1, "Unknown ECC param version code")
           .start_cons(SEQUENCE)
            .decode_and_check(OID("1.2.840.10045.1.1"),
                              "Only prime ECC fields supported")
             .decode(p)
           .end_cons()
           .start_cons(SEQUENCE)
             .decode_octet_string_bigint(a)
             .decode_octet_string_bigint(b)
           .end_cons()
           .decode(sv_base_point, OCTET_STRING)
           .decode(m_order)
           .decode(m_cofactor)
         .end_cons()
         .verify_end();

      m_curve = CurveGFp(p, a, b);
      m_base_point = OS2ECP(sv_base_point, m_curve);
      }
   else
      throw Decoding_Error("Unexpected tag while decoding ECC domain params");
   }
Exemplo n.º 10
0
Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier&,
                                           const secure_vector<byte>& key_bits)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
      .decode(m_public, OCTET_STRING)
      .verify_end()
   .end_cons();

   size_check(m_public.size(), "public key");
   }
Exemplo n.º 11
0
Ed25519_PrivateKey::Ed25519_PrivateKey(const AlgorithmIdentifier&,
                                       const secure_vector<uint8_t>& key_bits)
   {
   secure_vector<uint8_t> bits;
   BER_Decoder(key_bits).decode(bits, OCTET_STRING).discard_remaining();

   if(bits.size() != 32)
      throw Decoding_Error("Invalid size for Ed25519 private key");
   m_public.resize(32);
   m_private.resize(64);
   ed25519_gen_keypair(m_public.data(), m_private.data(), bits.data());
   }
Exemplo n.º 12
0
/*
* Extract a public key and return it
*/
Public_Key* load_key(DataSource& source)
   {
   try {
      AlgorithmIdentifier alg_id;
      secure_vector<byte> key_bits;

      if(ASN1::maybe_BER(source) && !PEM_Code::matches(source))
         {
         BER_Decoder(source)
            .start_cons(SEQUENCE)
            .decode(alg_id)
            .decode(key_bits, BIT_STRING)
            .verify_end()
         .end_cons();
         }
      else
         {
         DataSource_Memory ber(
            PEM_Code::decode_check_label(source, "PUBLIC KEY")
            );

         BER_Decoder(ber)
            .start_cons(SEQUENCE)
            .decode(alg_id)
            .decode(key_bits, BIT_STRING)
            .verify_end()
         .end_cons();
         }

      if(key_bits.empty())
         throw Decoding_Error("X.509 public key decoding failed");

      return make_public_key(alg_id, key_bits);
      }
   catch(Decoding_Error& e)
      {
      throw Decoding_Error("X.509 public key decoding failed: " + std::string(e.what()));
      }
   }
Exemplo n.º 13
0
std::vector<byte> CertID::extract_key_bitstr(const X509_Certificate& cert) const
   {
   const auto key_bits = cert.subject_public_key_bits();

   AlgorithmIdentifier public_key_algid;
   std::vector<byte> public_key_bitstr;

   BER_Decoder(key_bits)
      .decode(public_key_algid)
      .decode(public_key_bitstr, BIT_STRING);

   return public_key_bitstr;
   }
Exemplo n.º 14
0
secure_vector<uint8_t>
pbes2_decrypt(const secure_vector<uint8_t>& key_bits,
              const std::string& passphrase,
              const std::vector<uint8_t>& params)
   {
   AlgorithmIdentifier kdf_algo, enc_algo;

   BER_Decoder(params)
      .start_cons(SEQUENCE)
         .decode(kdf_algo)
         .decode(enc_algo)
      .end_cons();

   const std::string cipher = OIDS::lookup(enc_algo.get_oid());
   const 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_pbes_cipher_mode(cipher_spec[1]))
      throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher);

   secure_vector<uint8_t> iv;
   BER_Decoder(enc_algo.get_parameters()).decode(iv, OCTET_STRING).verify_end();

   std::unique_ptr<Cipher_Mode> dec = Cipher_Mode::create(cipher, DECRYPTION);
   if(!dec)
      throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher);

   dec->set_key(derive_key(passphrase, kdf_algo, dec->key_spec().maximum_keylength()));

   dec->start(iv);

   secure_vector<uint8_t> buf = key_bits;
   dec->finish(buf);

   return buf;
   }
Exemplo n.º 15
0
Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&,
                                             const secure_vector<byte>& key_bits,
                                             RandomNumberGenerator& rng)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
      .decode(m_public, OCTET_STRING)
      .decode(m_private, OCTET_STRING)
      .verify_end()
   .end_cons();

   size_check(m_public.size(), "public key");
   size_check(m_private.size(), "private key");

   load_check(rng);
   }
Exemplo n.º 16
0
         void key_bits(const MemoryRegion<byte>& bits)
            {
            u32bit version;
            SecureVector<byte> octstr_secret;

            BER_Decoder(bits)
               .start_cons(SEQUENCE)
               .decode(version)
               .decode(octstr_secret, OCTET_STRING)
               .verify_end()
               .end_cons();

            key->m_private_value = BigInt::decode(octstr_secret, octstr_secret.size());

            if(version != 1)
               throw Decoding_Error("Wrong PKCS #1 key format version for EC key");

            key->PKCS8_load_hook();
            }
Exemplo n.º 17
0
IF_Scheme_PrivateKey::IF_Scheme_PrivateKey(RandomNumberGenerator& rng,
                                           const AlgorithmIdentifier&,
                                           const secure_vector<byte>& key_bits)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
         .decode_and_check<size_t>(0, "Unknown PKCS #1 key format version")
         .decode(m_n)
         .decode(m_e)
         .decode(m_d)
         .decode(m_p)
         .decode(m_q)
         .decode(m_d1)
         .decode(m_d2)
         .decode(m_c)
      .end_cons();

   load_check(rng);
   }
Exemplo n.º 18
0
void EAC1_1_ADO::force_decode()
   {
   SecureVector<byte> inner_cert;
   BER_Decoder(tbs_bits)
      .start_cons(ASN1_Tag(33))
      .raw_bytes(inner_cert)
      .end_cons()
      .decode(m_car)
      .verify_end();

   SecureVector<byte> req_bits = DER_Encoder()
      .start_cons(ASN1_Tag(33), APPLICATION)
      .raw_bytes(inner_cert)
      .end_cons()
      .get_contents();

   DataSource_Memory req_source(req_bits);
   m_req = EAC1_1_Req(req_source);
   sig_algo = m_req.sig_algo;
   }
Exemplo n.º 19
0
Response::Response(const Certificate_Store& trusted_roots,
                   const std::vector<byte>& response_bits)
   {
   BER_Decoder response_outer = BER_Decoder(response_bits).start_cons(SEQUENCE);

   size_t resp_status = 0;

   response_outer.decode(resp_status, ENUMERATED, UNIVERSAL);

   if(resp_status != 0)
      throw std::runtime_error("OCSP response status " + std::to_string(resp_status));

   if(response_outer.more_items())
      {
      BER_Decoder response_bytes =
         response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE);

      response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"),
                                      "Unknown response type in OCSP response");

      BER_Decoder basicresponse =
         BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE);

      std::vector<byte> tbs_bits;
      AlgorithmIdentifier sig_algo;
      std::vector<byte> signature;
      std::vector<X509_Certificate> certs;

      basicresponse.start_cons(SEQUENCE)
           .raw_bytes(tbs_bits)
         .end_cons()
         .decode(sig_algo)
         .decode(signature, BIT_STRING);
      decode_optional_list(basicresponse, ASN1_Tag(0), certs);

      size_t responsedata_version = 0;
      X509_DN name;
      std::vector<byte> key_hash;
      X509_Time produced_at;
      Extensions extensions;

      BER_Decoder(tbs_bits)
         .decode_optional(responsedata_version, ASN1_Tag(0),
                          ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))

         .decode_optional(name, ASN1_Tag(1),
                          ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))

         .decode_optional_string(key_hash, OCTET_STRING, 2,
                                 ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))

         .decode(produced_at)

         .decode_list(m_responses)

         .decode_optional(extensions, ASN1_Tag(1),
                          ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));

      if(certs.empty())
         {
         if(auto cert = trusted_roots.find_cert(name, std::vector<byte>()))
            certs.push_back(*cert);
         else
            throw std::runtime_error("Could not find certificate that signed OCSP response");
         }

      check_signature(tbs_bits, sig_algo, signature, trusted_roots, certs);
      }

   response_outer.end_cons();
   }
Exemplo n.º 20
0
secure_vector<uint8_t>
pbes2_decrypt(const secure_vector<uint8_t>& key_bits,
              const std::string& passphrase,
              const std::vector<uint8_t>& params)
   {
   AlgorithmIdentifier kdf_algo, enc_algo;

   BER_Decoder(params)
      .start_cons(SEQUENCE)
         .decode(kdf_algo)
         .decode(enc_algo)
      .end_cons();

   AlgorithmIdentifier prf_algo;

   if(kdf_algo.oid != OIDS::lookup("PKCS5.PBKDF2"))
      throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " +
                           kdf_algo.oid.as_string());

   secure_vector<uint8_t> salt;
   size_t iterations = 0, key_length = 0;

   BER_Decoder(kdf_algo.parameters)
      .start_cons(SEQUENCE)
         .decode(salt, OCTET_STRING)
         .decode(iterations)
         .decode_optional(key_length, INTEGER, UNIVERSAL)
         .decode_optional(prf_algo, SEQUENCE, CONSTRUCTED,
                          AlgorithmIdentifier("HMAC(SHA-160)",
                                              AlgorithmIdentifier::USE_NULL_PARAM))
      .end_cons();

   const std::string cipher = OIDS::lookup(enc_algo.oid);
   const 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(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM")
      throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher);

   if(salt.size() < 8)
      throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small");

   secure_vector<uint8_t> iv;
   BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end();

   const std::string prf = OIDS::lookup(prf_algo.oid);

   std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")"));

   std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(cipher, DECRYPTION));
   if(!dec)
      throw Decoding_Error("PBE-PKCS5 cannot decrypt no cipher " + cipher);

   if(key_length == 0)
      key_length = dec->key_spec().maximum_keylength();

   dec->set_key(pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations));

   dec->start(iv);

   secure_vector<uint8_t> buf = key_bits;
   dec->finish(buf);

   return buf;
   }