OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/common/ssl_status_serialization.h" | |
6 | |
7 #include <stdint.h> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/numerics/safe_conversions.h" | |
11 #include "base/pickle.h" | |
12 | |
13 namespace { | |
14 | |
15 // Checks that an integer |security_style| is a valid SecurityStyle enum | |
16 // value. Returns true if valid, false otherwise. | |
17 bool CheckSecurityStyle(int security_style) { | |
18 switch (security_style) { | |
19 case content::SECURITY_STYLE_UNKNOWN: | |
20 case content::SECURITY_STYLE_UNAUTHENTICATED: | |
21 case content::SECURITY_STYLE_AUTHENTICATION_BROKEN: | |
22 case content::SECURITY_STYLE_WARNING: | |
23 case content::SECURITY_STYLE_AUTHENTICATED: | |
24 return true; | |
25 } | |
26 return false; | |
27 } | |
28 | |
29 // Checks that an integer |sct_status| is a valid net::ct::SCTVerifyStatus enum | |
30 // value. Returns true if valid, false otherwise. | |
31 bool CheckSCTStatus(uint32_t sct_status) { | |
32 switch (sct_status) { | |
33 case net::ct::SCT_STATUS_LOG_UNKNOWN: | |
34 // INVALID is deprecated and should not be used anymore, but it | |
35 // might have been previously written into the disk cache. | |
36 case net::ct::SCT_STATUS_INVALID: | |
37 case net::ct::SCT_STATUS_INVALID_SIGNATURE: | |
38 case net::ct::SCT_STATUS_OK: | |
39 case net::ct::SCT_STATUS_INVALID_TIMESTAMP: | |
40 return true; | |
41 case net::ct::SCT_STATUS_NONE: | |
42 // SCT_STATUS_NONE should never happen, so it isn't valid to | |
43 // receive a status of NONE in a serialized SSLStatus. | |
44 return false; | |
45 } | |
46 return false; | |
47 } | |
48 | |
49 } // namespace | |
50 | |
51 namespace content { | |
52 | |
53 std::string SerializeSecurityInfo(const SSLStatus& ssl_status) { | |
54 base::Pickle pickle; | |
55 pickle.WriteInt(ssl_status.security_style); | |
56 pickle.WriteInt(ssl_status.cert_id); | |
57 pickle.WriteUInt32(ssl_status.cert_status); | |
58 pickle.WriteInt(ssl_status.security_bits); | |
59 pickle.WriteInt(ssl_status.key_exchange_info); | |
60 pickle.WriteInt(ssl_status.connection_status); | |
61 pickle.WriteUInt32(ssl_status.sct_statuses.size()); | |
62 for (const auto& sct_status : ssl_status.sct_statuses) { | |
63 pickle.WriteUInt32(sct_status); | |
64 } | |
65 pickle.WriteBool(ssl_status.pkp_bypassed); | |
66 return std::string(static_cast<const char*>(pickle.data()), pickle.size()); | |
67 } | |
68 | |
69 bool DeserializeSecurityInfo(const std::string& state, SSLStatus* ssl_status) { | |
70 *ssl_status = SSLStatus(); | |
71 | |
72 if (state.empty()) { | |
73 // No SSL used. | |
74 return true; | |
75 } | |
76 | |
77 base::Pickle pickle(state.data(), base::checked_cast<int>(state.size())); | |
78 base::PickleIterator iter(pickle); | |
79 int security_style; | |
80 if (!iter.ReadInt(&security_style) || !iter.ReadInt(&ssl_status->cert_id) || | |
81 !iter.ReadUInt32(&ssl_status->cert_status) || | |
82 !iter.ReadInt(&ssl_status->security_bits) || | |
83 !iter.ReadInt(&ssl_status->key_exchange_info) || | |
84 !iter.ReadInt(&ssl_status->connection_status)) { | |
85 *ssl_status = SSLStatus(); | |
86 return false; | |
87 } | |
88 | |
89 uint32_t num_sct_statuses; | |
90 if (!iter.ReadUInt32(&num_sct_statuses)) { | |
91 return false; | |
92 } | |
93 | |
94 for (uint32_t i = 0; i < num_sct_statuses; i++) { | |
95 uint32_t sct_status; | |
96 if (!iter.ReadUInt32(&sct_status) || !CheckSCTStatus(sct_status)) { | |
97 *ssl_status = SSLStatus(); | |
98 return false; | |
99 } | |
100 ssl_status->sct_statuses.push_back( | |
101 static_cast<net::ct::SCTVerifyStatus>(sct_status)); | |
102 } | |
103 | |
104 if (!iter.ReadBool(&ssl_status->pkp_bypassed)) { | |
105 *ssl_status = SSLStatus(); | |
106 return false; | |
107 } | |
108 | |
109 if (!CheckSecurityStyle(security_style)) { | |
110 *ssl_status = SSLStatus(); | |
111 return false; | |
112 } | |
113 | |
114 ssl_status->security_style = static_cast<SecurityStyle>(security_style); | |
115 | |
116 // Sanity check |security_bits|: the only allowed negative value is -1. | |
117 if (ssl_status->security_bits < -1) { | |
118 *ssl_status = SSLStatus(); | |
119 return false; | |
120 } | |
121 | |
122 // Sanity check |key_exchange_info|: 0 or greater. | |
123 if (ssl_status->key_exchange_info < 0) { | |
124 *ssl_status = SSLStatus(); | |
125 return false; | |
126 } | |
127 | |
128 return true; | |
129 } | |
130 | |
131 } // namespace content | |
OLD | NEW |