Botan  1.11.15
src/lib/tls/msg_cert_req.cpp
Go to the documentation of this file.
00001 /*
00002 * Certificate Request Message
00003 * (C) 2004-2006,2012 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/tls_messages.h>
00009 #include <botan/internal/tls_reader.h>
00010 #include <botan/internal/tls_extensions.h>
00011 #include <botan/internal/tls_handshake_io.h>
00012 #include <botan/der_enc.h>
00013 #include <botan/ber_dec.h>
00014 #include <botan/loadstor.h>
00015 
00016 namespace Botan {
00017 
00018 namespace TLS {
00019 
00020 namespace {
00021 
00022 std::string cert_type_code_to_name(byte code)
00023    {
00024    switch(code)
00025       {
00026       case 1:
00027          return "RSA";
00028       case 2:
00029          return "DSA";
00030       case 64:
00031          return "ECDSA";
00032       default:
00033          return ""; // DH or something else
00034       }
00035    }
00036 
00037 byte cert_type_name_to_code(const std::string& name)
00038    {
00039    if(name == "RSA")
00040       return 1;
00041    if(name == "DSA")
00042       return 2;
00043    if(name == "ECDSA")
00044       return 64;
00045 
00046    throw Invalid_Argument("Unknown cert type " + name);
00047    }
00048 
00049 }
00050 
00051 /**
00052 * Create a new Certificate Request message
00053 */
00054 Certificate_Req::Certificate_Req(Handshake_IO& io,
00055                                  Handshake_Hash& hash,
00056                                  const Policy& policy,
00057                                  const std::vector<X509_DN>& ca_certs,
00058                                  Protocol_Version version) :
00059    m_names(ca_certs),
00060    m_cert_key_types({ "RSA", "DSA", "ECDSA" })
00061    {
00062    if(version.supports_negotiable_signature_algorithms())
00063       {
00064       std::vector<std::string> hashes = policy.allowed_signature_hashes();
00065       std::vector<std::string> sigs = policy.allowed_signature_methods();
00066 
00067       for(size_t i = 0; i != hashes.size(); ++i)
00068          for(size_t j = 0; j != sigs.size(); ++j)
00069             m_supported_algos.push_back(std::make_pair(hashes[i], sigs[j]));
00070       }
00071 
00072    hash.update(io.send(*this));
00073    }
00074 
00075 /**
00076 * Deserialize a Certificate Request message
00077 */
00078 Certificate_Req::Certificate_Req(const std::vector<byte>& buf,
00079                                  Protocol_Version version)
00080    {
00081    if(buf.size() < 4)
00082       throw Decoding_Error("Certificate_Req: Bad certificate request");
00083 
00084    TLS_Data_Reader reader("CertificateRequest", buf);
00085 
00086    std::vector<byte> cert_type_codes = reader.get_range_vector<byte>(1, 1, 255);
00087 
00088    for(size_t i = 0; i != cert_type_codes.size(); ++i)
00089       {
00090       const std::string cert_type_name = cert_type_code_to_name(cert_type_codes[i]);
00091 
00092       if(cert_type_name == "") // something we don't know
00093          continue;
00094 
00095       m_cert_key_types.push_back(cert_type_name);
00096       }
00097 
00098    if(version.supports_negotiable_signature_algorithms())
00099       {
00100       std::vector<byte> sig_hash_algs = reader.get_range_vector<byte>(2, 2, 65534);
00101 
00102       if(sig_hash_algs.size() % 2 != 0)
00103          throw Decoding_Error("Bad length for signature IDs in certificate request");
00104 
00105       for(size_t i = 0; i != sig_hash_algs.size(); i += 2)
00106          {
00107          std::string hash = Signature_Algorithms::hash_algo_name(sig_hash_algs[i]);
00108          std::string sig = Signature_Algorithms::sig_algo_name(sig_hash_algs[i+1]);
00109          m_supported_algos.push_back(std::make_pair(hash, sig));
00110          }
00111       }
00112 
00113    const u16bit purported_size = reader.get_u16bit();
00114 
00115    if(reader.remaining_bytes() != purported_size)
00116       throw Decoding_Error("Inconsistent length in certificate request");
00117 
00118    while(reader.has_remaining())
00119       {
00120       std::vector<byte> name_bits = reader.get_range_vector<byte>(2, 0, 65535);
00121 
00122       BER_Decoder decoder(&name_bits[0], name_bits.size());
00123       X509_DN name;
00124       decoder.decode(name);
00125       m_names.push_back(name);
00126       }
00127    }
00128 
00129 /**
00130 * Serialize a Certificate Request message
00131 */
00132 std::vector<byte> Certificate_Req::serialize() const
00133    {
00134    std::vector<byte> buf;
00135 
00136    std::vector<byte> cert_types;
00137 
00138    for(size_t i = 0; i != m_cert_key_types.size(); ++i)
00139       cert_types.push_back(cert_type_name_to_code(m_cert_key_types[i]));
00140 
00141    append_tls_length_value(buf, cert_types, 1);
00142 
00143    if(!m_supported_algos.empty())
00144       buf += Signature_Algorithms(m_supported_algos).serialize();
00145 
00146    std::vector<byte> encoded_names;
00147 
00148    for(size_t i = 0; i != m_names.size(); ++i)
00149       {
00150       DER_Encoder encoder;
00151       encoder.encode(m_names[i]);
00152 
00153       append_tls_length_value(encoded_names, encoder.get_contents(), 2);
00154       }
00155 
00156    append_tls_length_value(buf, encoded_names, 2);
00157 
00158    return buf;
00159    }
00160 
00161 }
00162 
00163 }