Botan  1.10.9
s_kex.cpp
Go to the documentation of this file.
1 /*
2 * Server 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/dsa.h>
14 #include <botan/loadstor.h>
15 #include <memory>
16 
17 namespace Botan {
18 
19 /**
20 * Create a new Server Key Exchange message
21 */
23  Record_Writer& writer,
24  const Public_Key* kex_key,
25  const Private_Key* priv_key,
26  const MemoryRegion<byte>& c_random,
27  const MemoryRegion<byte>& s_random,
28  HandshakeHash& hash)
29  {
30  const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(kex_key);
31  const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(kex_key);
32 
33  if(dh_pub)
34  {
35  params.push_back(dh_pub->get_domain().get_p());
36  params.push_back(dh_pub->get_domain().get_g());
37  params.push_back(BigInt::decode(dh_pub->public_value()));
38  }
39  else if(rsa_pub)
40  {
41  params.push_back(rsa_pub->get_n());
42  params.push_back(rsa_pub->get_e());
43  }
44  else
45  throw Invalid_Argument("Bad key for TLS key exchange: not DH or RSA");
46 
47 
48  std::string padding = "";
49  Signature_Format format = IEEE_1363;
50 
51  if(priv_key->algo_name() == "RSA")
52  padding = "EMSA3(TLS.Digest.0)";
53  else if(priv_key->algo_name() == "DSA")
54  {
55  padding = "EMSA1(SHA-1)";
56  format = DER_SEQUENCE;
57  }
58  else
59  throw Invalid_Argument(priv_key->algo_name() +
60  " is invalid/unknown for TLS signatures");
61 
62  PK_Signer signer(*priv_key, padding, format);
63 
64  signer.update(c_random);
65  signer.update(s_random);
66  signer.update(serialize_params());
67  signature = signer.signature(rng);
68 
69  send(writer, hash);
70  }
71 
72 /**
73 * Serialize a Server Key Exchange message
74 */
75 SecureVector<byte> Server_Key_Exchange::serialize() const
76  {
77  SecureVector<byte> buf = serialize_params();
78  append_tls_length_value(buf, signature, 2);
79  return buf;
80  }
81 
82 /**
83 * Serialize the ServerParams structure
84 */
85 SecureVector<byte> Server_Key_Exchange::serialize_params() const
86  {
87  SecureVector<byte> buf;
88 
89  for(size_t i = 0; i != params.size(); ++i)
90  append_tls_length_value(buf, BigInt::encode(params[i]), 2);
91 
92  return buf;
93  }
94 
95 /**
96 * Deserialize a Server Key Exchange message
97 */
98 void Server_Key_Exchange::deserialize(const MemoryRegion<byte>& buf)
99  {
100  if(buf.size() < 6)
101  throw Decoding_Error("Server_Key_Exchange: Packet corrupted");
102 
103  SecureVector<byte> values[4];
104  size_t so_far = 0;
105 
106  for(size_t i = 0; i != 4; ++i)
107  {
108  const u16bit len = make_u16bit(buf[so_far], buf[so_far+1]);
109  so_far += 2;
110 
111  if(len + so_far > buf.size())
112  throw Decoding_Error("Server_Key_Exchange: Packet corrupted");
113 
114  values[i].resize(len);
115  copy_mem(&values[i][0], &buf[so_far], len);
116  so_far += len;
117 
118  if(i == 2 && so_far == buf.size())
119  break;
120  }
121 
122  params.push_back(BigInt::decode(values[0]));
123  params.push_back(BigInt::decode(values[1]));
124  if(values[3].size())
125  {
126  params.push_back(BigInt::decode(values[2]));
127  signature = values[3];
128  }
129  else
130  signature = values[2];
131  }
132 
133 /**
134 * Return the public key
135 */
137  {
138  if(params.size() == 2)
139  return new RSA_PublicKey(params[0], params[1]);
140  else if(params.size() == 3)
141  return new DH_PublicKey(DL_Group(params[0], params[1]), params[2]);
142  else
143  throw Internal_Error("Server_Key_Exchange::key: No key set");
144  }
145 
146 /**
147 * Verify a Server Key Exchange message
148 */
150  const MemoryRegion<byte>& c_random,
151  const MemoryRegion<byte>& s_random) const
152  {
153 
154  std::auto_ptr<Public_Key> key(cert.subject_public_key());
155 
156  std::string padding = "";
157  Signature_Format format = IEEE_1363;
158 
159  if(key->algo_name() == "RSA")
160  padding = "EMSA3(TLS.Digest.0)";
161  else if(key->algo_name() == "DSA")
162  {
163  padding = "EMSA1(SHA-1)";
164  format = DER_SEQUENCE;
165  }
166  else
167  throw Invalid_Argument(key->algo_name() +
168  " is invalid/unknown for TLS signatures");
169 
170  PK_Verifier verifier(*key, padding, format);
171 
172  SecureVector<byte> params_got = serialize_params();
173  verifier.update(c_random);
174  verifier.update(s_random);
175  verifier.update(params_got);
176 
177  return verifier.check_signature(signature);
178  }
179 
180 }
void append_tls_length_value(MemoryRegion< byte > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:145
void send(Record_Writer &, HandshakeHash &) const
Definition: hello.cpp:16
const BigInt & get_e() const
Definition: if_algo.h:44
Public_Key * key() const
Definition: s_kex.cpp:136
Signature_Format
Definition: pubkey.h:24
virtual std::string algo_name() const =0
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
const BigInt & get_p() const
Definition: dl_group.cpp:176
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
bool verify(const X509_Certificate &, const MemoryRegion< byte > &, const MemoryRegion< byte > &) const
Definition: s_kex.cpp:149
MemoryVector< byte > public_value() const
Definition: dh.cpp:27
RandomNumberGenerator * rng
Definition: global_rng.cpp:165
const BigInt & get_g() const
Definition: dl_group.cpp:185
const DL_Group & get_domain() const
Definition: dl_algo.h:33
unsigned short u16bit
Definition: types.h:27
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
Server_Key_Exchange(RandomNumberGenerator &rng, Record_Writer &, const Public_Key *, const Private_Key *, const MemoryRegion< byte > &, const MemoryRegion< byte > &, HandshakeHash &)
Definition: s_kex.cpp:22
u16bit make_u16bit(byte i0, byte i1)
Definition: loadstor.h:47
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:102
const BigInt & get_n() const
Definition: if_algo.h:39
Public_Key * subject_public_key() const
Definition: x509cert.cpp:196