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