Botan 1.10.17
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
17namespace 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*/
78SecureVector<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*/
93void 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*/
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}
TLS_Ciphersuite_Algos kex_type() const
Definition tls_suites.h:30
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
SecureVector< byte > pre_master_secret() const
Definition c_kex.cpp:160
MemoryVector< byte > public_value() const
Definition dh.cpp:74
void send(Record_Writer &, HandshakeHash &) const
Definition hello.cpp:16
SecureVector< byte > bits_of() const
Definition symkey.h:30
SecureVector< byte > decrypt(const byte in[], size_t length) const
Definition pubkey.h:94
SecureVector< byte > encrypt(const byte in[], size_t length, RandomNumberGenerator &rng) const
Definition pubkey.h:48
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 > random_vec(size_t bytes)
Definition rng.h:40
u16bit make_u16bit(byte i0, byte i1)
Definition loadstor.h:47
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
@ TLS_ALGO_KEYEXCH_RSA
Definition tls_magic.h:154
void append_tls_length_value(MemoryRegion< byte > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition tls_reader.h:145
Version_Code
Definition tls_magic.h:22
@ SSL_V3
Definition tls_magic.h:24
Decoding_Error(const std::string &name)
Definition exceptn.h:140