Botan  1.10.9
c_kex.cpp
Go to the documentation of this file.
1 /*
2 * Client Key Exchange Message
3 * (C) 2004-2010 Jack Lloyd
4 *
5 * Released under the terms of the Botan license
6 */
7 
8 #include <botan/internal/tls_messages.h>
9 #include <botan/internal/tls_reader.h>
10 #include <botan/pubkey.h>
11 #include <botan/dh.h>
12 #include <botan/rsa.h>
13 #include <botan/rng.h>
14 #include <botan/loadstor.h>
15 #include <memory>
16 
17 namespace Botan {
18 
19 /**
20 * Create a new Client Key Exchange message
21 */
23  Record_Writer& writer,
24  HandshakeHash& hash,
25  const Public_Key* pub_key,
26  Version_Code using_version,
27  Version_Code pref_version)
28  {
29  include_length = true;
30 
31  if(const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(pub_key))
32  {
33  DH_PrivateKey priv_key(rng, dh_pub->get_domain());
34 
35  PK_Key_Agreement ka(priv_key, "Raw");
36 
37  pre_master = ka.derive_key(0, dh_pub->public_value()).bits_of();
38 
39  key_material = priv_key.public_value();
40  }
41  else if(const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(pub_key))
42  {
43  pre_master = rng.random_vec(48);
44  pre_master[0] = (pref_version >> 8) & 0xFF;
45  pre_master[1] = (pref_version ) & 0xFF;
46 
47  PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15");
48 
49  key_material = encryptor.encrypt(pre_master, rng);
50 
51  if(using_version == SSL_V3)
52  include_length = false;
53  }
54  else
55  throw Invalid_Argument("Client_Key_Exchange: Key not RSA or DH");
56 
57  send(writer, hash);
58  }
59 
60 /**
61 * Read a Client Key Exchange message
62 */
64  const CipherSuite& suite,
65  Version_Code using_version)
66  {
67  include_length = true;
68 
69  if(using_version == SSL_V3 && (suite.kex_type() == TLS_ALGO_KEYEXCH_RSA))
70  include_length = false;
71 
72  deserialize(contents);
73  }
74 
75 /**
76 * Serialize a Client Key Exchange message
77 */
78 SecureVector<byte> Client_Key_Exchange::serialize() const
79  {
80  if(include_length)
81  {
83  append_tls_length_value(buf, key_material, 2);
84  return buf;
85  }
86  else
87  return key_material;
88  }
89 
90 /**
91 * Deserialize a Client Key Exchange message
92 */
93 void Client_Key_Exchange::deserialize(const MemoryRegion<byte>& buf)
94  {
95  if(include_length)
96  {
97  TLS_Data_Reader reader(buf);
98  key_material = reader.get_range<byte>(2, 0, 65535);
99  }
100  else
101  key_material = buf;
102  }
103 
104 /**
105 * Return the pre_master_secret
106 */
107 SecureVector<byte>
109  const Private_Key* priv_key,
110  Version_Code version)
111  {
112 
113  if(const DH_PrivateKey* dh_priv = dynamic_cast<const DH_PrivateKey*>(priv_key))
114  {
115  try {
116  PK_Key_Agreement ka(*dh_priv, "Raw");
117 
118  pre_master = ka.derive_key(0, key_material).bits_of();
119  }
120  catch(...)
121  {
122  /*
123  * Something failed in the DH computation. To avoid possible
124  * timing attacks, randomize the pre-master output and carry
125  * on, allowing the protocol to fail later in the finished
126  * checks.
127  */
128  pre_master = rng.random_vec(dh_priv->public_value().size());
129  }
130 
131  return pre_master;
132  }
133  else if(const RSA_PrivateKey* rsa_priv = dynamic_cast<const RSA_PrivateKey*>(priv_key))
134  {
135  PK_Decryptor_EME decryptor(*rsa_priv, "PKCS1v15");
136 
137  try {
138  pre_master = decryptor.decrypt(key_material);
139 
140  if(pre_master.size() != 48 ||
141  make_u16bit(pre_master[0], pre_master[1]) != version)
142  throw Decoding_Error("Client_Key_Exchange: Secret corrupted");
143  }
144  catch(...)
145  {
146  pre_master = rng.random_vec(48);
147  pre_master[0] = (version >> 8) & 0xFF;
148  pre_master[1] = (version ) & 0xFF;
149  }
150 
151  return pre_master;
152  }
153  else
154  throw Invalid_Argument("Client_Key_Exchange: Bad key for decrypt");
155  }
156 
157 /**
158 * Return the pre_master_secret
159 */
161  {
162  return pre_master;
163  }
164 
165 }
void append_tls_length_value(MemoryRegion< byte > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:145
SecureVector< byte > decrypt(const byte in[], size_t length) const
Definition: pubkey.h:94
void send(Record_Writer &, HandshakeHash &) const
Definition: hello.cpp:16
SecureVector< byte > random_vec(size_t bytes)
Definition: rng.h:40
SymmetricKey derive_key(size_t key_len, const byte in[], size_t in_len, const byte params[], size_t params_len) const
Definition: pubkey.cpp:379
SecureVector< byte > pre_master_secret() const
Definition: c_kex.cpp:160
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
TLS_Ciphersuite_Algos kex_type() const
Definition: tls_suites.h:30
unsigned char byte
Definition: types.h:22
SecureVector< byte > bits_of() const
Definition: symkey.h:30
RandomNumberGenerator * rng
Definition: global_rng.cpp:165
Version_Code
Definition: tls_magic.h:22
size_t size() const
Definition: secmem.h:29
SecureVector< byte > encrypt(const byte in[], size_t length, RandomNumberGenerator &rng) const
Definition: pubkey.h:48
u16bit make_u16bit(byte i0, byte i1)
Definition: loadstor.h:47
Client_Key_Exchange(RandomNumberGenerator &rng, Record_Writer &output, HandshakeHash &hash, const Public_Key *my_key, Version_Code using_version, Version_Code pref_version)
Definition: c_kex.cpp:22