1 /*
2 * Certificate Verify 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/rsa.h>
12 #include <botan/dsa.h>
13 #include <botan/loadstor.h>
14 #include <memory>
15
16 namespace Botan {
17
18 /**
19 * Create a new Certificate Verify message
20 */
Certificate_Verify(RandomNumberGenerator & rng,Record_Writer & writer,HandshakeHash & hash,const Private_Key * priv_key)21 Certificate_Verify::Certificate_Verify(RandomNumberGenerator& rng,
22 Record_Writer& writer,
23 HandshakeHash& hash,
24 const Private_Key* priv_key)
25 {
26 std::string padding = "";
27 Signature_Format format = IEEE_1363;
28
29 if(priv_key->algo_name() == "RSA")
30 padding = "EMSA3(TLS.Digest.0)";
31 else if(priv_key->algo_name() == "DSA")
32 {
33 padding = "EMSA1(SHA-1)";
34 format = DER_SEQUENCE;
35 }
36 else
37 throw Invalid_Argument(priv_key->algo_name() +
38 " is invalid/unknown for TLS signatures");
39
40 PK_Signer signer(*priv_key, padding, format);
41
42 signature = signer.sign_message(hash.final(), rng);
43 send(writer, hash);
44 }
45
46 /**
47 * Serialize a Certificate Verify message
48 */
serialize() const49 SecureVector<byte> Certificate_Verify::serialize() const
50 {
51 SecureVector<byte> buf;
52
53 const u16bit sig_len = signature.size();
54 buf.push_back(get_byte(0, sig_len));
55 buf.push_back(get_byte(1, sig_len));
56 buf += signature;
57
58 return buf;
59 }
60
61 /**
62 * Deserialize a Certificate Verify message
63 */
deserialize(const MemoryRegion<byte> & buf)64 void Certificate_Verify::deserialize(const MemoryRegion<byte>& buf)
65 {
66 TLS_Data_Reader reader(buf);
67 signature = reader.get_range<byte>(2, 0, 65535);
68 }
69
70 /**
71 * Verify a Certificate Verify message
72 */
verify(const X509_Certificate & cert,HandshakeHash & hash)73 bool Certificate_Verify::verify(const X509_Certificate& cert,
74 HandshakeHash& hash)
75 {
76 // FIXME: duplicate of Server_Key_Exchange::verify
77
78 std::auto_ptr<Public_Key> key(cert.subject_public_key());
79
80 std::string padding = "";
81 Signature_Format format = IEEE_1363;
82
83 if(key->algo_name() == "RSA")
84 padding = "EMSA3(TLS.Digest.0)";
85 else if(key->algo_name() == "DSA")
86 {
87 padding = "EMSA1(SHA-1)";
88 format = DER_SEQUENCE;
89 }
90 else
91 throw Invalid_Argument(key->algo_name() +
92 " is invalid/unknown for TLS signatures");
93
94 PK_Verifier verifier(*key, padding, format);
95 return verifier.verify_message(hash.final(), signature);
96 }
97
98 }
99